From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from EUR03-DB5-obe.outbound.protection.outlook.com (EUR03-DB5-obe.outbound.protection.outlook.com [40.107.4.60]) by mx.groups.io with SMTP id smtpd.web09.3066.1638910729169273605 for ; Tue, 07 Dec 2021 12:58:49 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@armh.onmicrosoft.com header.s=selector2-armh-onmicrosoft-com header.b=KNOdL3pz; spf=pass (domain: arm.com, ip: 40.107.4.60, mailfrom: sami.mujawar@arm.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=tZS0pDK/8F3ug8wq6wJVdE9GaBkzyDnE3kTgJQrddCQ=; b=KNOdL3pzo3McXOXTshyuZAfD+x17u4bwrdwo9m9d+EekQR4ghFa3dHBIx1a0HccAGZjzPRfp4scWIhOci/Xfh2ff4fjhc+kamkysggPRYjd2a8cWl6z2PHWLavVeugpF/O+HZJtAdaZdTM6FlfPj2FaBoGidxbfH8/YIb2ajgMg= Received: from AS9PR06CA0255.eurprd06.prod.outlook.com (2603:10a6:20b:45f::26) by DB9PR08MB6874.eurprd08.prod.outlook.com (2603:10a6:10:2ac::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4755.21; Tue, 7 Dec 2021 20:58:44 +0000 Received: from AM5EUR03FT007.eop-EUR03.prod.protection.outlook.com (2603:10a6:20b:45f:cafe::96) by AS9PR06CA0255.outlook.office365.com (2603:10a6:20b:45f::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4755.17 via Frontend Transport; Tue, 7 Dec 2021 20:58:44 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by AM5EUR03FT007.mail.protection.outlook.com (10.152.16.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4755.13 via Frontend Transport; Tue, 7 Dec 2021 20:58:44 +0000 Received: ("Tessian outbound de6049708a0a:v110"); Tue, 07 Dec 2021 20:58:44 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: a39607c77d2b6e09 X-CR-MTA-TID: 64aa7808 Received: from 4f18c2dc1433.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id C0492B90-C9D4-46E8-A0A0-1860A276E953.1; Tue, 07 Dec 2021 20:58:33 +0000 Received: from EUR04-HE1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 4f18c2dc1433.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Tue, 07 Dec 2021 20:58:33 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=oWNB9dkKqweDkcC1jiR5sI8XtNzpumS/V+IOhjob6u4c4Zhu08ndcMoMFiIPPhfjmSWJQJxzMG1gZH/Szc2UCAwS8l4wDb8+gA0VM6Ahmvd6tuatG6Z7mnzKnR2MU+U0H22xtXC+zHWBC3iesCFqTtT5/2wAJk9OrA7JJeOZQllmW7aOZnu9b1C3dnDDVNvkLs+OdVl4/QXsjZZdTGorCGjTtIaJH9lE4YYfYUDJfWYWDcFP/IHHAabMYPqbkPqb1GdzFF5+Mdmd2cKtyBm4WsGmm1aPwhdoInnLIuzRi57ka6CNsUl9RZyHnmVApu66toryxlnYT6zIaLKQ0SrT+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=tZS0pDK/8F3ug8wq6wJVdE9GaBkzyDnE3kTgJQrddCQ=; b=LxPDONjha8Q4oT21e5O8uksQOWLIUfYFcgzJdtrIdj0F+gMCZ/DtEZycCCjtR2Tv+Yz/Zp+M8xW8Q7/K51JdAlJRPcVpPvJyiXYFBWJk4pmMfVsOgDXp7J10Bo+Sp/yw0PKou46CR7M0HyD1UwyCJFJ3kT97XNuIKuCmKPjAIjt8joBg7zKhF2qw5wmilhQYwRdMlWNGgdpuZUXxVe0nbnH3QvfufGSEEUuWZ+uAfL4qvt0mCmVJ10vg8KRI2KBWpR/AJ6WFaWydCULjIY9wLNvamHOlGiZC/8JnLQ9Ru+eZ0Wfw26DWNF+1lq9T1yG8tIJpIyj2S5fm9WB2YtUrSA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=tZS0pDK/8F3ug8wq6wJVdE9GaBkzyDnE3kTgJQrddCQ=; b=KNOdL3pzo3McXOXTshyuZAfD+x17u4bwrdwo9m9d+EekQR4ghFa3dHBIx1a0HccAGZjzPRfp4scWIhOci/Xfh2ff4fjhc+kamkysggPRYjd2a8cWl6z2PHWLavVeugpF/O+HZJtAdaZdTM6FlfPj2FaBoGidxbfH8/YIb2ajgMg= Authentication-Results-Original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; Received: from AS8PR08MB6806.eurprd08.prod.outlook.com (2603:10a6:20b:39b::12) by AM6PR08MB4472.eurprd08.prod.outlook.com (2603:10a6:20b:bf::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4755.11; Tue, 7 Dec 2021 20:58:30 +0000 Received: from AS8PR08MB6806.eurprd08.prod.outlook.com ([fe80::bdcf:cfa6:b2bb:38ac]) by AS8PR08MB6806.eurprd08.prod.outlook.com ([fe80::bdcf:cfa6:b2bb:38ac%6]) with mapi id 15.20.4755.021; Tue, 7 Dec 2021 20:58:30 +0000 Subject: Re: [edk2-platforms][PATCH V1 07/11] Platform/ARM/Morello: Port PCI Express library To: Chandni Cherukuri , devel@edk2.groups.io Cc: Ard Biesheuvel , Leif Lindholm References: <20211204123042.32140-1-chandni.cherukuri@arm.com> <20211204123042.32140-8-chandni.cherukuri@arm.com> From: "Sami Mujawar" Message-ID: <2d695d9d-eb38-f8d0-d7bd-d77dbe609ec3@arm.com> Date: Tue, 7 Dec 2021 20:58:35 +0000 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.0.1 In-Reply-To: <20211204123042.32140-8-chandni.cherukuri@arm.com> X-ClientProxiedBy: LO4P123CA0519.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:272::6) To AS8PR08MB6806.eurprd08.prod.outlook.com (2603:10a6:20b:39b::12) MIME-Version: 1.0 Received: from [10.1.196.43] (217.140.106.50) by LO4P123CA0519.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:272::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4755.17 via Frontend Transport; Tue, 7 Dec 2021 20:58:30 +0000 X-MS-Office365-Filtering-Correlation-Id: 9acf51d5-bd53-40df-dbd6-08d9b9c45b1e X-MS-TrafficTypeDiagnostic: AM6PR08MB4472:EE_|AM5EUR03FT007:EE_|DB9PR08MB6874:EE_ X-Microsoft-Antispam-PRVS: x-checkrecipientrouted: true NoDisclaimer: true X-MS-Oob-TLC-OOBClassifiers: OLM:8882;OLM:8882; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: 9C0XYcgPePQNFUtyUWLpbanBlchQed7CH9CFCmDnfsto3L+yPQ9e8y/SrYrVM726uVJ+gWoyL+0Sizum3L9kYymr1TnIKOZrKY8lWdQkdBIs9Trc9MRPU6FeXjOSyf7+N51I0X5lrqQhhX7A7/t8OxiLdBvyuHr1SWV4qdmXsZ0Rrk5K6njB3/k2k8VngobWhnzoWZ8OQwEOD8z+7Fd0ds/tgJ3qNmDtUJwSHbV41RZvkmMRHNp0Bf1jmbQGAWeUkY3OcfUm1XcDYcgMbyfHlVoSiKHuCc3Mau1S10Br0lmTbq2c9lQMo9A4u9TTIKXVZmslH0cZd0XenClLlA0obrmedcmxUU4GZdd2ag5MELURRhi3XuHR+7EC5MK9EezVcnuizeZp/7NNWbp8yBIQQHGCV5FcJGQw2608RtFmjPdeX8jsAYQ5If5Ggi4KCTOcdzDgBkuWDc+4BF2AYLnMZKwcTRyboQpwHDxAnId+J+QDhVVzXBmBLNlo12V43o/fWgoGM+VLbH1taInVPkqEwNTs4ojq+kbeUbQCPrT37TIOy2n12Ly8e5B9plNBZ2brUkHI3GWNFhy+XO1h1fKuQBVHw7ZZZtaH9KNrVg+BnruBWZ7frZ05je5DgI84in9jrLvoIh3KwNkwtozLObh6v40qMeFkzpjT1YmKxzKsMc+V389L+xaqazLLdcDy5ozk4SzxjkS9+YxbQx16O8NbbWja+mNcPJhRvuDyzYg0BtAXaMsbfemf6fRe+V/nFy5RqFlcTSV8DvjP2gSIXhzeWA== X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AS8PR08MB6806.eurprd08.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(366004)(30864003)(508600001)(19627235002)(316002)(44832011)(36756003)(38350700002)(16576012)(83380400001)(52116002)(186003)(38100700002)(956004)(86362001)(54906003)(8936002)(26005)(4326008)(2616005)(31686004)(53546011)(66556008)(8676002)(31696002)(2906002)(5660300002)(6486002)(66946007)(66476007)(45980500001)(43740500002)(579004)(559001);DIR:OUT;SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6PR08MB4472 Original-Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; Return-Path: Sami.Mujawar@arm.com X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: AM5EUR03FT007.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 50bdbf54-7256-49e1-157d-08d9b9c452c5 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: jkmNCrmaUda+WyOEoVnYadi7kWpQd9105x9QPlxNOBojWIoR0YNxSlZcMVl2/cN8n3rBv8U29HcxT8iOoiFp/kR5QNbStOq3rh5CxRY2R1ykWAH4s33pu0jCaN4Hzv+4u0RprCAIg75rmLoGJ3XhDiQSM2D92n4hCTaag5RrU7SZF2D3rGo3PT424bbExhDqZi41q+m1Er4/UDRhi3PqF8koEVl38ExJP6ljHQM11kJL1j+WsN3/11tlaA9pG+lbKNlvP/eWpj2amyhL4mCmnomkZZ1T6FMdmBAWXvKDHonpVb4B/S8zHYN5jMVXfuvYnnZGCcgtha6ExHkvRSQQYRx4uPAq+V2T5fzIFl/55dZfb9vfGwy4OAVNMUBoJP+2Ia/ii2Q8Zu6Y8miy+Lcps/viCqBQcxI912PMHM1O45c9I7F4OBKxkoPwi+7fLPQbDM9TnzRhIRwaUZgmR9qIsLFXzVc0R6pLIqtpO3ghNJNdlhBiY0xyQfZRe7M8EDdKZOb+UYTZbfwIyZcXWIvBc19ByZEn3Zy22vs/wbtRH1q8ENHzl0nk77itKUgUd0W91JbVzt5ZrtZ2Kxa7BjMZrQqdzjSjUlb5gLy9yiA8xIVxbjK1Add0tm6EdL8XoJjkBtPNWXTQB1I/G1Im46bxj9EopjfqExs25ek/VZ905BNmFYAHhl0OVUO+C4hE6C53+cbrGVaqzy21+tCWswEB1wjq5BfcD/HQHpVn3BTM2tc= X-Forefront-Antispam-Report: CIP:63.35.35.123;CTRY:IE;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:64aa7808-outbound-1.mta.getcheckrecipient.com;PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com;CAT:NONE;SFS:(4636009)(36840700001)(46966006)(107886003)(70586007)(47076005)(82310400004)(86362001)(31696002)(6486002)(36756003)(2906002)(70206006)(19627235002)(81166007)(4326008)(8676002)(31686004)(53546011)(336012)(54906003)(16576012)(356005)(44832011)(8936002)(316002)(36860700001)(83380400001)(30864003)(186003)(26005)(5660300002)(2616005)(956004)(508600001)(43740500002)(579004)(559001);DIR:OUT;SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Dec 2021 20:58:44.2332 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 9acf51d5-bd53-40df-dbd6-08d9b9c45b1e X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d;Ip=[63.35.35.123];Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: AM5EUR03FT007.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR08MB6874 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable Content-Language: en-GB Hi Chandni, Thank you for this patch. Please find my feedback inline marked [SAMI]. With those addressed. Reviewed-by: Sami Mujawar Regards, Sami Mujawar On 04/12/2021 12:30 PM, Chandni Cherukuri wrote: > From: Anurag Koul > > Morello platform requires a custom platform-specific PCI Express > library because the native PCI Express Library only allows for a > single ECAM config address to be supplied to it. If there is more > than one PCIe root port, it expects the ECAM regions for all the > root ports to be contiguous. This is not the case with Morello where > the two RPs have their ECAM regions mapped to non-contiguous address > ranges and reside in separate PCIe segments. > > This custom plaform-specific PCI Express library, inherited from > MdePkg/BasePciExpressLib, routes the ECAM accesses to the appropriate > ECAM region based on the PCIe segment number in the incoming PCIe > address. > > Signed-off-by: Anurag Koul > Signed-off-by: Chandni Cherukuri > --- > Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.inf | 49 + > Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.c | 1431 +++= +++++++++++++++++ > Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.uni | 18 + > 3 files changed, 1498 insertions(+) > > diff --git a/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.inf= b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.inf > new file mode 100644 > index 000000000000..71a2cf3a6276 > --- /dev/null > +++ b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.inf > @@ -0,0 +1,49 @@ > +## @file > +# Instance of PCI Express Library using the 256 MB PCI Express MMIO win= dow. > +# > +# PCI Express Library that uses the 256 MB PCI Express MMIO window to p= erform > +# PCI Configuration cycles. Layers on top of an I/O Library instance. > +# > +# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved. > +# > +# This library is inherited from MdePkg/Library/BasePciExpressLib to wo= rk with > +# non-contiguous ECAM regions for the two supported PCIe root ports. Th= e > +# base PCI Express library expects the ECAM space for all the available= root > +# ports to be contiguous and hence exposes only a single hook(variable)= to > +# hold the ECAM base address informaion in. > + > +# This library reinterprets the ECAM accesses and routes them to the > +# appropriate Root Port Config based on the PCIe segment number in the > +# incoming PCIe address. [SAMI] Is it possible to keep the copyright list together, please? Maybe it would be good to move the comment above at the beginning of the file. [/SAMI] > +# > +# Copyright (c) 2021, ARM Limited. All rights reserved.
> + > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION =3D 0x0001001B > + BASE_NAME =3D PciExpressLib > + MODULE_UNI_FILE =3D PciExpressLib.uni > + FILE_GUID =3D 795fad20-e353-45f8-b77f-c59eb790737= 0 > + MODULE_TYPE =3D BASE > + VERSION_STRING =3D 1.0 > + LIBRARY_CLASS =3D PciExpressLib > + > +[Sources] > + PciExpressLib.c > + > +[Packages] > + MdePkg/MdePkg.dec > + Platform/ARM/Morello/MorelloPlatform.dec > + > +[LibraryClasses] > + BaseLib > + DebugLib > + IoLib > + PcdLib > + > +[Pcd] > + gArmMorelloTokenSpaceGuid.PcdCcixExpressBaseAddress ## CONSUMES > + gArmMorelloTokenSpaceGuid.PcdPciExpressBaseAddress ## CONSUMES > diff --git a/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.c b= /Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.c > new file mode 100644 > index 000000000000..8f0652dc6678 > --- /dev/null > +++ b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.c > @@ -0,0 +1,1431 @@ > +/** @file > + Functions in this library instance make use of MMIO functions in IoLib= to > + access memory mapped PCI configuration space. > + > + All assertions for I/O operations are handled in MMIO functions in the= IoLib > + Library. > + > + Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
> + > + On Morello platform, the PCIe ECAM regions for the two supported Root = Ports, > + which lie in separate PCIe segments, are not contiguous. As such, any = ECAM > + access from the PCI Express library should ideally be routed based on = the > + segment number within the incoming address, which is configured in the > + platform PCI Host Bridge library. > + > + Copyright (c) 2021, ARM Limited. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** > + Assert the validity of a PCI address. A valid PCI address may contain = 1's > + only in the low 33 bits. Bit 32 carries the segment number which could= be > + either 0 or 1. > + > + @param A The address to validate. > + > +**/ > +#define ASSERT_INVALID_PCI_ADDRESS(A) \ > + ASSERT (((A) & ~0x1ffffffffULL) =3D=3D 0) > + > +#define GET_SEG_NUM(Address) ((Address >> 32ULL) & 0x1) > + > +/** > + Registers a PCI device so PCI configuration registers may be accessed = after > + SetVirtualAddressMap(). > + > + Registers the PCI device specified by Address so all the PCI configura= tion > + registers associated with that PCI device may be accessed after > + SetVirtualAddressMap() is called. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + > + @param [in] Address The address that encodes the PCI Bus, Device, Fun= ction and > + Register. > + > + @retval RETURN_UNSUPPORTED An attempt was made to call this func= tion > + after ExitBootServices(). > + The resources required to access the = PCI > + device at runtime could not be mapped= . > + > +**/ > +RETURN_STATUS > +EFIAPI > +PciExpressRegisterForRuntimeAccess ( > + IN UINTN Address > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return RETURN_UNSUPPORTED; > +} > + > +/** > + Gets the base address of PCI Express. > + > + This internal functions retrieves PCI Express Base Address via a PCD e= ntry. > + > + @param [in] Address The address that encodes the PCI Segment, Bus, De= vice, > + Function and Register. > + > + @return The converted address relative to PCI Root's ECAM base address= . > + > +**/ > +STATIC > +VOID * [SAMI] Can the return type be changed to UINTN? It would remove the need to typecase every time this function is used. > +GetPciExpressAddress ( > + IN UINTN Address > + ) > +{ > + UINTN ConvAddress; > + > + ASSERT_INVALID_PCI_ADDRESS (Address); > + > + if (GET_SEG_NUM (Address) =3D=3D 0) { > + ConvAddress =3D PcdGet64 (PcdPciExpressBaseAddress) + (UINT32)Addres= s; > + } else if (GET_SEG_NUM (Address) =3D=3D 1) { > + ConvAddress =3D PcdGet64 (PcdCcixExpressBaseAddress) + (UINT32)Addre= ss; > + } else { > + DEBUG ((DEBUG_ERROR, "PciExpressLib: Invalid PCIe Address.\n")); > + ASSERT (FALSE); > + return NULL; > + } > + > + return (VOID *)ConvAddress; > +} > + > +/** > + Reads an 8-bit PCI configuration register. > + > + Reads and returns the 8-bit PCI configuration register specified by Ad= dress. > + This function must guarantee that all PCI read and write operations ar= e > + serialized. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + > + @param [in] Address The address that encodes the PCI Bus, Device, Fun= ction and > + Register. > + > + @return The read value from the PCI configuration register. > + > +**/ > +UINT8 > +EFIAPI > +PciExpressRead8 ( > + IN UINTN Address > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioRead8 ((UINTN)GetPciExpressAddress (Address)); > +} > + > +/** > + Writes an 8-bit PCI configuration register. > + > + Writes the 8-bit PCI configuration register specified by Address with = the > + value specified by Value. Value is returned. This function must guaran= tee > + that all PCI read and write operations are serialized. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + > + @param [in] Address The address that encodes the PCI Bus, Device, Fun= ction and > + Register. > + @param [in] Value The value to write. > + > + @return The value written to the PCI configuration register. > + > +**/ > +UINT8 > +EFIAPI > +PciExpressWrite8 ( > + IN UINTN Address, > + IN UINT8 Value > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + > + return MmioWrite8 ((UINTN)GetPciExpressAddress (Address), Value); > +} > + > +/** > + Performs a bitwise OR of an 8-bit PCI configuration register with > + an 8-bit value. > + > + Reads the 8-bit PCI configuration register specified by Address, perfo= rms a > + bitwise OR between the read result and the value specified by > + OrData, and writes the result to the 8-bit PCI configuration register > + specified by Address. The value written to the PCI configuration regis= ter is > + returned. This function must guarantee that all PCI read and write ope= rations > + are serialized. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + > + @param [in] Address The address that encodes the PCI Bus, Device, Fun= ction and > + Register. > + @param [in] OrData The value to OR with the PCI configuration regist= er. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT8 > +EFIAPI > +PciExpressOr8 ( > + IN UINTN Address, > + IN UINT8 OrData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioOr8 ((UINTN)GetPciExpressAddress (Address), OrData); > +} > + > +/** > + Performs a bitwise AND of an 8-bit PCI configuration register with an = 8-bit > + value. > + > + Reads the 8-bit PCI configuration register specified by Address, perfo= rms a > + bitwise AND between the read result and the value specified by AndData= , and > + writes the result to the 8-bit PCI configuration register specified by > + Address. The value written to the PCI configuration register is return= ed. > + This function must guarantee that all PCI read and write operations ar= e > + serialized. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + > + @param [in] Address The address that encodes the PCI Bus, Device, Fun= ction and > + Register. > + @param [in] AndData The value to AND with the PCI configuration regis= ter. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT8 > +EFIAPI > +PciExpressAnd8 ( > + IN UINTN Address, > + IN UINT8 AndData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioAnd8 ((UINTN)GetPciExpressAddress (Address), AndData); > +} > + > +/** > + Performs a bitwise AND of an 8-bit PCI configuration register with an = 8-bit > + value, followed a bitwise OR with another 8-bit value. > + > + Reads the 8-bit PCI configuration register specified by Address, perfo= rms a > + bitwise AND between the read result and the value specified by AndData= , > + performs a bitwise OR between the result of the AND operation and > + the value specified by OrData, and writes the result to the 8-bit PCI > + configuration register specified by Address. The value written to the = PCI > + configuration register is returned. This function must guarantee that = all PCI > + read and write operations are serialized. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + > + @param [in] Address The address that encodes the PCI Bus, Device, Fun= ction and > + Register. > + @param [in] AndData The value to AND with the PCI configuration regis= ter. > + @param [in] OrData The value to OR with the result of the AND operat= ion. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT8 > +EFIAPI > +PciExpressAndThenOr8 ( > + IN UINTN Address, > + IN UINT8 AndData, > + IN UINT8 OrData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioAndThenOr8 ( > + (UINTN)GetPciExpressAddress (Address), > + AndData, > + OrData > + ); > +} > + > +/** > + Reads a bit field of a PCI configuration register. > + > + Reads the bit field in an 8-bit PCI configuration register. The bit fi= eld is > + specified by the StartBit and the EndBit. The value of the bit field i= s > + returned. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If StartBit is greater than 7, then ASSERT(). > + If EndBit is greater than 7, then ASSERT(). > + If EndBit is less than StartBit, then ASSERT(). > + > + @param [in] Address The PCI configuration register to read. > + @param [in] StartBit The ordinal of the least significant bit in the= bit > + field. Range 0..7. > + @param [in] EndBit The ordinal of the most significant bit in the = bit > + field. Range 0..7. > + > + @return The value of the bit field read from the PCI configuration reg= ister. > + > +**/ > +UINT8 > +EFIAPI > +PciExpressBitFieldRead8 ( > + IN UINTN Address, > + IN UINTN StartBit, > + IN UINTN EndBit > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioBitFieldRead8 ( > + (UINTN)GetPciExpressAddress (Address), > + StartBit, > + EndBit > + ); > +} > + > +/** > + Writes a bit field to a PCI configuration register. > + > + Writes Value to the bit field of the PCI configuration register. The b= it > + field is specified by the StartBit and the EndBit. All other bits in t= he > + destination PCI configuration register are preserved. The new value of= the > + 8-bit register is returned. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If StartBit is greater than 7, then ASSERT(). > + If EndBit is greater than 7, then ASSERT(). > + If EndBit is less than StartBit, then ASSERT(). > + If Value is larger than the bitmask value range specified by StartBit = and > + EndBit, then ASSERT(). > + > + @param [in] Address The PCI configuration register to write. > + @param [in] StartBit The ordinal of the least significant bit in the= bit > + field. Range 0..7. > + @param [in] EndBit The ordinal of the most significant bit in the = bit > + field. Range 0..7. > + @param [in] Value The new value of the bit field. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT8 > +EFIAPI > +PciExpressBitFieldWrite8 ( > + IN UINTN Address, > + IN UINTN StartBit, > + IN UINTN EndBit, > + IN UINT8 Value > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioBitFieldWrite8 ( > + (UINTN)GetPciExpressAddress (Address), > + StartBit, > + EndBit, > + Value > + ); > +} > + > +/** > + Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR= , and > + writes the result back to the bit field in the 8-bit port. > + > + Reads the 8-bit PCI configuration register specified by Address, perfo= rms a > + bitwise OR between the read result and the value specified by > + OrData, and writes the result to the 8-bit PCI configuration register > + specified by Address. The value written to the PCI configuration regis= ter is > + returned. This function must guarantee that all PCI read and write ope= rations > + are serialized. Extra left bits in OrData are stripped. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If StartBit is greater than 7, then ASSERT(). > + If EndBit is greater than 7, then ASSERT(). > + If EndBit is less than StartBit, then ASSERT(). > + If OrData is larger than the bitmask value range specified by StartBit= and > + EndBit, then ASSERT(). > + > + @param [in] Address The PCI configuration register to write. > + @param [in] StartBit The ordinal of the least significant bit in the= bit > + field. Range 0..7. > + @param [in] EndBit The ordinal of the most significant bit in the = bit > + field. Range 0..7. > + @param [in] OrData The value to OR with the PCI configuration regi= ster. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT8 > +EFIAPI > +PciExpressBitFieldOr8 ( > + IN UINTN Address, > + IN UINTN StartBit, > + IN UINTN EndBit, > + IN UINT8 OrData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioBitFieldOr8 ( > + (UINTN)GetPciExpressAddress (Address), > + StartBit, > + EndBit, > + OrData > + ); > +} > + > +/** > + Reads a bit field in an 8-bit PCI configuration register, performs a b= itwise > + AND, and writes the result back to the bit field in the 8-bit register= . > + > + Reads the 8-bit PCI configuration register specified by Address, perfo= rms a > + bitwise AND between the read result and the value specified by AndData= , and > + writes the result to the 8-bit PCI configuration register specified by > + Address. The value written to the PCI configuration register is return= ed. > + This function must guarantee that all PCI read and write operations ar= e > + serialized. Extra left bits in AndData are stripped. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If StartBit is greater than 7, then ASSERT(). > + If EndBit is greater than 7, then ASSERT(). > + If EndBit is less than StartBit, then ASSERT(). > + If AndData is larger than the bitmask value range specified by StartBi= t and > + EndBit, then ASSERT(). > + > + @param [in] Address The PCI configuration register to write. > + @param [in] StartBit The ordinal of the least significant bit in the= bit > + field. Range 0..7. > + @param [in] EndBit The ordinal of the most significant bit in the = bit > + field. Range 0..7. > + @param [in] AndData The value to AND with the PCI configuration reg= ister. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT8 > +EFIAPI > +PciExpressBitFieldAnd8 ( > + IN UINTN Address, > + IN UINTN StartBit, > + IN UINTN EndBit, > + IN UINT8 AndData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioBitFieldAnd8 ( > + (UINTN)GetPciExpressAddress (Address), > + StartBit, > + EndBit, > + AndData > + ); > +} > + > +/** > + Reads a bit field in an 8-bit port, performs a bitwise AND followed by= a > + bitwise OR, and writes the result back to the bit field in the > + 8-bit port. > + > + Reads the 8-bit PCI configuration register specified by Address, perfo= rms a > + bitwise AND followed by a bitwise OR between the read result and > + the value specified by AndData, and writes the result to the 8-bit PCI > + configuration register specified by Address. The value written to the = PCI > + configuration register is returned. This function must guarantee that = all PCI > + read and write operations are serialized. Extra left bits in both AndD= ata and > + OrData are stripped. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If StartBit is greater than 7, then ASSERT(). > + If EndBit is greater than 7, then ASSERT(). > + If EndBit is less than StartBit, then ASSERT(). > + If AndData is larger than the bitmask value range specified by StartBi= t and > + EndBit, then ASSERT(). > + If OrData is larger than the bitmask value range specified by StartBit= and > + EndBit, then ASSERT(). > + > + @param [in] Address The PCI configuration register to write. > + @param [in] StartBit The ordinal of the least significant bit in the= bit > + field. Range 0..7. > + @param [in] EndBit The ordinal of the most significant bit in the = bit > + field. Range 0..7. > + @param [in] AndData The value to AND with the PCI configuration reg= ister. > + @param [in] OrData The value to OR with the result of the AND oper= ation. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT8 > +EFIAPI > +PciExpressBitFieldAndThenOr8 ( > + IN UINTN Address, > + IN UINTN StartBit, > + IN UINTN EndBit, > + IN UINT8 AndData, > + IN UINT8 OrData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioBitFieldAndThenOr8 ( > + (UINTN)GetPciExpressAddress (Address), > + StartBit, > + EndBit, > + AndData, > + OrData > + ); > +} > + > +/** > + Reads a 16-bit PCI configuration register. > + > + Reads and returns the 16-bit PCI configuration register specified by A= ddress. > + This function must guarantee that all PCI read and write operations ar= e > + serialized. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > + > + @param [in] Address The address that encodes the PCI Bus, Device, Fun= ction and > + Register. > + > + @return The read value from the PCI configuration register. > + > +**/ > +UINT16 > +EFIAPI > +PciExpressRead16 ( > + IN UINTN Address > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioRead16 ((UINTN)GetPciExpressAddress (Address)); > +} > + > +/** > + Writes a 16-bit PCI configuration register. > + > + Writes the 16-bit PCI configuration register specified by Address with= the > + value specified by Value. Value is returned. This function must guaran= tee > + that all PCI read and write operations are serialized. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > + > + @param [in] Address The address that encodes the PCI Bus, Device, Fun= ction and > + Register. > + @param [in] Value The value to write. > + > + @return The value written to the PCI configuration register. > + > +**/ > +UINT16 > +EFIAPI > +PciExpressWrite16 ( > + IN UINTN Address, > + IN UINT16 Value > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + > + return MmioWrite16 ((UINTN)GetPciExpressAddress (Address), Value); > +} > + > +/** > + Performs a bitwise OR of a 16-bit PCI configuration register with > + a 16-bit value. > + > + Reads the 16-bit PCI configuration register specified by Address, perf= orms a > + bitwise OR between the read result and the value specified by > + OrData, and writes the result to the 16-bit PCI configuration register > + specified by Address. The value written to the PCI configuration regis= ter is > + returned. This function must guarantee that all PCI read and write ope= rations > + are serialized. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > + > + @param [in] Address The address that encodes the PCI Bus, Device, Fun= ction and > + Register. > + @param [in] OrData The value to OR with the PCI configuration regist= er. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT16 > +EFIAPI > +PciExpressOr16 ( > + IN UINTN Address, > + IN UINT16 OrData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioOr16 ((UINTN)GetPciExpressAddress (Address), OrData); > +} > + > +/** > + Performs a bitwise AND of a 16-bit PCI configuration register with a 1= 6-bit > + value. > + > + Reads the 16-bit PCI configuration register specified by Address, perf= orms a > + bitwise AND between the read result and the value specified by AndData= , and > + writes the result to the 16-bit PCI configuration register specified b= y > + Address. The value written to the PCI configuration register is return= ed. > + This function must guarantee that all PCI read and write operations ar= e > + serialized. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > + > + @param [in] Address The address that encodes the PCI Bus, Device, Fun= ction and > + Register. > + @param [in] AndData The value to AND with the PCI configuration regis= ter. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT16 > +EFIAPI > +PciExpressAnd16 ( > + IN UINTN Address, > + IN UINT16 AndData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioAnd16 ((UINTN)GetPciExpressAddress (Address), AndData); > +} > + > +/** > + Performs a bitwise AND of a 16-bit PCI configuration register with a 1= 6-bit > + value, followed a bitwise OR with another 16-bit value. > + > + Reads the 16-bit PCI configuration register specified by Address, perf= orms a > + bitwise AND between the read result and the value specified by AndData= , > + performs a bitwise OR between the result of the AND operation and > + the value specified by OrData, and writes the result to the 16-bit PCI > + configuration register specified by Address. The value written to the = PCI > + configuration register is returned. This function must guarantee that = all PCI > + read and write operations are serialized. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > + > + @param [in] Address The address that encodes the PCI Bus, Device, Fun= ction and > + Register. > + @param [in] AndData The value to AND with the PCI configuration regis= ter. > + @param [in] OrData The value to OR with the result of the AND operat= ion. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT16 > +EFIAPI > +PciExpressAndThenOr16 ( > + IN UINTN Address, > + IN UINT16 AndData, > + IN UINT16 OrData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioAndThenOr16 ( > + (UINTN)GetPciExpressAddress (Address), > + AndData, > + OrData > + ); > +} > + > +/** > + Reads a bit field of a PCI configuration register. > + > + Reads the bit field in a 16-bit PCI configuration register. The bit fi= eld is > + specified by the StartBit and the EndBit. The value of the bit field i= s > + returned. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > + If StartBit is greater than 15, then ASSERT(). > + If EndBit is greater than 15, then ASSERT(). > + If EndBit is less than StartBit, then ASSERT(). > + > + @param [in] Address The PCI configuration register to read. > + @param [in] StartBit The ordinal of the least significant bit in the= bit > + field. Range 0..15. > + @param [in] EndBit The ordinal of the most significant bit in the = bit > + field. Range 0..15. > + > + @return The value of the bit field read from the PCI configuration reg= ister. > + > +**/ > +UINT16 > +EFIAPI > +PciExpressBitFieldRead16 ( > + IN UINTN Address, > + IN UINTN StartBit, > + IN UINTN EndBit > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioBitFieldRead16 ( > + (UINTN)GetPciExpressAddress (Address), > + StartBit, > + EndBit > + ); > +} > + > +/** > + Writes a bit field to a PCI configuration register. > + > + Writes Value to the bit field of the PCI configuration register. The b= it > + field is specified by the StartBit and the EndBit. All other bits in t= he > + destination PCI configuration register are preserved. The new value of= the > + 16-bit register is returned. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > + If StartBit is greater than 15, then ASSERT(). > + If EndBit is greater than 15, then ASSERT(). > + If EndBit is less than StartBit, then ASSERT(). > + If Value is larger than the bitmask value range specified by StartBit = and > + EndBit, then ASSERT(). > + > + @param [in] Address The PCI configuration register to write. > + @param [in] StartBit The ordinal of the least significant bit in the= bit > + field. Range 0..15. > + @param [in] EndBit The ordinal of the most significant bit in the = bit > + field. Range 0..15. > + @param [in] Value The new value of the bit field. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT16 > +EFIAPI > +PciExpressBitFieldWrite16 ( > + IN UINTN Address, > + IN UINTN StartBit, > + IN UINTN EndBit, > + IN UINT16 Value > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioBitFieldWrite16 ( > + (UINTN)GetPciExpressAddress (Address), > + StartBit, > + EndBit, > + Value > + ); > +} > + > +/** > + Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR= , and > + writes the result back to the bit field in the 16-bit port. > + > + Reads the 16-bit PCI configuration register specified by Address, perf= orms a > + bitwise OR between the read result and the value specified by > + OrData, and writes the result to the 16-bit PCI configuration register > + specified by Address. The value written to the PCI configuration regis= ter is > + returned. This function must guarantee that all PCI read and write ope= rations > + are serialized. Extra left bits in OrData are stripped. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > + If StartBit is greater than 15, then ASSERT(). > + If EndBit is greater than 15, then ASSERT(). > + If EndBit is less than StartBit, then ASSERT(). > + If OrData is larger than the bitmask value range specified by StartBit= and > + EndBit, then ASSERT(). > + > + @param [in] Address The PCI configuration register to write. > + @param [in] StartBit The ordinal of the least significant bit in the= bit > + field. Range 0..15. > + @param [in] EndBit The ordinal of the most significant bit in the = bit > + field. Range 0..15. > + @param [in] OrData The value to OR with the PCI configuration regi= ster. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT16 > +EFIAPI > +PciExpressBitFieldOr16 ( > + IN UINTN Address, > + IN UINTN StartBit, > + IN UINTN EndBit, > + IN UINT16 OrData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioBitFieldOr16 ( > + (UINTN)GetPciExpressAddress (Address), > + StartBit, > + EndBit, > + OrData > + ); > +} > + > +/** > + Reads a bit field in a 16-bit PCI configuration register, performs a b= itwise > + AND, and writes the result back to the bit field in the 16-bit registe= r. > + > + Reads the 16-bit PCI configuration register specified by Address, perf= orms a > + bitwise AND between the read result and the value specified by AndData= , and > + writes the result to the 16-bit PCI configuration register specified b= y > + Address. The value written to the PCI configuration register is return= ed. > + This function must guarantee that all PCI read and write operations ar= e > + serialized. Extra left bits in AndData are stripped. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > + If StartBit is greater than 15, then ASSERT(). > + If EndBit is greater than 15, then ASSERT(). > + If EndBit is less than StartBit, then ASSERT(). > + If AndData is larger than the bitmask value range specified by StartBi= t and > + EndBit, then ASSERT(). > + > + @param [in] Address The PCI configuration register to write. > + @param [in] StartBit The ordinal of the least significant bit in the= bit > + field. Range 0..15. > + @param [in] EndBit The ordinal of the most significant bit in the = bit > + field. Range 0..15. > + @param [in] AndData The value to AND with the PCI configuration reg= ister. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT16 > +EFIAPI > +PciExpressBitFieldAnd16 ( > + IN UINTN Address, > + IN UINTN StartBit, > + IN UINTN EndBit, > + IN UINT16 AndData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioBitFieldAnd16 ( > + (UINTN)GetPciExpressAddress (Address), > + StartBit, > + EndBit, > + AndData > + ); > +} > + > +/** > + Reads a bit field in a 16-bit port, performs a bitwise AND followed by= a > + bitwise OR, and writes the result back to the bit field in the > + 16-bit port. > + > + Reads the 16-bit PCI configuration register specified by Address, perf= orms a > + bitwise AND followed by a bitwise OR between the read result and > + the value specified by AndData, and writes the result to the 16-bit PC= I > + configuration register specified by Address. The value written to the = PCI > + configuration register is returned. This function must guarantee that = all PCI > + read and write operations are serialized. Extra left bits in both AndD= ata and > + OrData are stripped. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > + If StartBit is greater than 15, then ASSERT(). > + If EndBit is greater than 15, then ASSERT(). > + If EndBit is less than StartBit, then ASSERT(). > + If AndData is larger than the bitmask value range specified by StartBi= t and > + EndBit, then ASSERT(). > + If OrData is larger than the bitmask value range specified by StartBit= and > + EndBit, then ASSERT(). > + > + @param [in] Address The PCI configuration register to write. > + @param [in] StartBit The ordinal of the least significant bit in the= bit > + field. Range 0..15. > + @param [in] EndBit The ordinal of the most significant bit in the = bit > + field. Range 0..15. > + @param [in] AndData The value to AND with the PCI configuration reg= ister. > + @param [in] OrData The value to OR with the result of the AND oper= ation. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT16 > +EFIAPI > +PciExpressBitFieldAndThenOr16 ( > + IN UINTN Address, > + IN UINTN StartBit, > + IN UINTN EndBit, > + IN UINT16 AndData, > + IN UINT16 OrData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioBitFieldAndThenOr16 ( > + (UINTN)GetPciExpressAddress (Address), > + StartBit, > + EndBit, > + AndData, > + OrData > + ); > +} > + > +/** > + Reads a 32-bit PCI configuration register. > + > + Reads and returns the 32-bit PCI configuration register specified by A= ddress. > + This function must guarantee that all PCI read and write operations ar= e > + serialized. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > + > + @param [in] Address The address that encodes the PCI Bus, Device, Fun= ction and > + Register. > + > + @return The read value from the PCI configuration register. > + > +**/ > +UINT32 > +EFIAPI > +PciExpressRead32 ( > + IN UINTN Address > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioRead32 ((UINTN)GetPciExpressAddress (Address)); > +} > + > +/** > + Writes a 32-bit PCI configuration register. > + > + Writes the 32-bit PCI configuration register specified by Address with= the > + value specified by Value. Value is returned. This function must guaran= tee > + that all PCI read and write operations are serialized. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > + > + @param [in] Address The address that encodes the PCI Bus, Device, Fun= ction and > + Register. > + @param [in] Value The value to write. > + > + @return The value written to the PCI configuration register. > + > +**/ > +UINT32 > +EFIAPI > +PciExpressWrite32 ( > + IN UINTN Address, > + IN UINT32 Value > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioWrite32 ((UINTN)GetPciExpressAddress (Address), Value); > +} > + > +/** > + Performs a bitwise OR of a 32-bit PCI configuration register with > + a 32-bit value. > + > + Reads the 32-bit PCI configuration register specified by Address, perf= orms a > + bitwise OR between the read result and the value specified by > + OrData, and writes the result to the 32-bit PCI configuration register > + specified by Address. The value written to the PCI configuration regis= ter is > + returned. This function must guarantee that all PCI read and write ope= rations > + are serialized. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > + > + @param [in] Address The address that encodes the PCI Bus, Device, Fun= ction and > + Register. > + @param [in] OrData The value to OR with the PCI configuration regist= er. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT32 > +EFIAPI > +PciExpressOr32 ( > + IN UINTN Address, > + IN UINT32 OrData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioOr32 ((UINTN)GetPciExpressAddress (Address), OrData); > +} > + > +/** > + Performs a bitwise AND of a 32-bit PCI configuration register with a 3= 2-bit > + value. > + > + Reads the 32-bit PCI configuration register specified by Address, perf= orms a > + bitwise AND between the read result and the value specified by AndData= , and > + writes the result to the 32-bit PCI configuration register specified b= y > + Address. The value written to the PCI configuration register is return= ed. > + This function must guarantee that all PCI read and write operations ar= e > + serialized. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > + > + @param [in] Address The address that encodes the PCI Bus, Device, Fun= ction and > + Register. > + @param [in] AndData The value to AND with the PCI configuration regis= ter. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT32 > +EFIAPI > +PciExpressAnd32 ( > + IN UINTN Address, > + IN UINT32 AndData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioAnd32 ((UINTN)GetPciExpressAddress (Address), AndData); > +} > + > +/** > + Performs a bitwise AND of a 32-bit PCI configuration register with a 3= 2-bit > + value, followed a bitwise OR with another 32-bit value. > + > + Reads the 32-bit PCI configuration register specified by Address, perf= orms a > + bitwise AND between the read result and the value specified by AndData= , > + performs a bitwise OR between the result of the AND operation and > + the value specified by OrData, and writes the result to the 32-bit PCI > + configuration register specified by Address. The value written to the = PCI > + configuration register is returned. This function must guarantee that = all PCI > + read and write operations are serialized. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > + > + @param [in] Address The address that encodes the PCI Bus, Device, Fun= ction and > + Register. > + @param [in] AndData The value to AND with the PCI configuration regis= ter. > + @param [in] OrData The value to OR with the result of the AND operat= ion. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT32 > +EFIAPI > +PciExpressAndThenOr32 ( > + IN UINTN Address, > + IN UINT32 AndData, > + IN UINT32 OrData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioAndThenOr32 ( > + (UINTN)GetPciExpressAddress (Address), > + AndData, > + OrData > + ); > +} > + > +/** > + Reads a bit field of a PCI configuration register. > + > + Reads the bit field in a 32-bit PCI configuration register. The bit fi= eld is > + specified by the StartBit and the EndBit. The value of the bit field i= s > + returned. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > + If StartBit is greater than 31, then ASSERT(). > + If EndBit is greater than 31, then ASSERT(). > + If EndBit is less than StartBit, then ASSERT(). > + > + @param [in] Address The PCI configuration register to read. > + @param [in] StartBit The ordinal of the least significant bit in the= bit > + field. Range 0..31. > + @param [in] EndBit The ordinal of the most significant bit in the = bit > + field. Range 0..31. > + > + @return The value of the bit field read from the PCI configuration reg= ister. > + > +**/ > +UINT32 > +EFIAPI > +PciExpressBitFieldRead32 ( > + IN UINTN Address, > + IN UINTN StartBit, > + IN UINTN EndBit > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioBitFieldRead32 ( > + (UINTN)GetPciExpressAddress (Address), > + StartBit, > + EndBit > + ); > +} > + > +/** > + Writes a bit field to a PCI configuration register. > + > + Writes Value to the bit field of the PCI configuration register. The b= it > + field is specified by the StartBit and the EndBit. All other bits in t= he > + destination PCI configuration register are preserved. The new value of= the > + 32-bit register is returned. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > + If StartBit is greater than 31, then ASSERT(). > + If EndBit is greater than 31, then ASSERT(). > + If EndBit is less than StartBit, then ASSERT(). > + If Value is larger than the bitmask value range specified by StartBit = and > + EndBit, then ASSERT(). > + > + @param [in] Address The PCI configuration register to write. > + @param [in] StartBit The ordinal of the least significant bit in the= bit > + field. Range 0..31. > + @param [in] EndBit The ordinal of the most significant bit in the = bit > + field. Range 0..31. > + @param [in] Value The new value of the bit field. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT32 > +EFIAPI > +PciExpressBitFieldWrite32 ( > + IN UINTN Address, > + IN UINTN StartBit, > + IN UINTN EndBit, > + IN UINT32 Value > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioBitFieldWrite32 ( > + (UINTN)GetPciExpressAddress (Address), > + StartBit, > + EndBit, > + Value > + ); > +} > + > +/** > + Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR= , and > + writes the result back to the bit field in the 32-bit port. > + > + Reads the 32-bit PCI configuration register specified by Address, perf= orms a > + bitwise OR between the read result and the value specified by > + OrData, and writes the result to the 32-bit PCI configuration register > + specified by Address. The value written to the PCI configuration regis= ter is > + returned. This function must guarantee that all PCI read and write ope= rations > + are serialized. Extra left bits in OrData are stripped. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > + If StartBit is greater than 31, then ASSERT(). > + If EndBit is greater than 31, then ASSERT(). > + If EndBit is less than StartBit, then ASSERT(). > + If OrData is larger than the bitmask value range specified by StartBit= and > + EndBit, then ASSERT(). > + > + @param [in] Address The PCI configuration register to write. > + @param [in] StartBit The ordinal of the least significant bit in the= bit > + field. Range 0..31. > + @param [in] EndBit The ordinal of the most significant bit in the = bit > + field. Range 0..31. > + @param [in] OrData The value to OR with the PCI configuration regi= ster. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT32 > +EFIAPI > +PciExpressBitFieldOr32 ( > + IN UINTN Address, > + IN UINTN StartBit, > + IN UINTN EndBit, > + IN UINT32 OrData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioBitFieldOr32 ( > + (UINTN)GetPciExpressAddress (Address), > + StartBit, > + EndBit, > + OrData > + ); > +} > + > +/** > + Reads a bit field in a 32-bit PCI configuration register, performs a b= itwise > + AND, and writes the result back to the bit field in the 32-bit registe= r. > + > + Reads the 32-bit PCI configuration register specified by Address, perf= orms a > + bitwise AND between the read result and the value specified by AndData= , and > + writes the result to the 32-bit PCI configuration register specified b= y > + Address. The value written to the PCI configuration register is return= ed. > + This function must guarantee that all PCI read and write operations ar= e > + serialized. Extra left bits in AndData are stripped. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > + If StartBit is greater than 31, then ASSERT(). > + If EndBit is greater than 31, then ASSERT(). > + If EndBit is less than StartBit, then ASSERT(). > + If AndData is larger than the bitmask value range specified by StartBi= t and > + EndBit, then ASSERT(). > + > + @param [in] Address The PCI configuration register to write. > + @param [in] StartBit The ordinal of the least significant bit in the= bit > + field. Range 0..31. > + @param [in] EndBit The ordinal of the most significant bit in the = bit > + field. Range 0..31. > + @param [in] AndData The value to AND with the PCI configuration reg= ister. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT32 > +EFIAPI > +PciExpressBitFieldAnd32 ( > + IN UINTN Address, > + IN UINTN StartBit, > + IN UINTN EndBit, > + IN UINT32 AndData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioBitFieldAnd32 ( > + (UINTN)GetPciExpressAddress (Address), > + StartBit, > + EndBit, > + AndData > + ); > +} > + > +/** > + Reads a bit field in a 32-bit port, performs a bitwise AND followed by= a > + bitwise OR, and writes the result back to the bit field in the > + 32-bit port. > + > + Reads the 32-bit PCI configuration register specified by Address, perf= orms a > + bitwise AND followed by a bitwise OR between the read result and > + the value specified by AndData, and writes the result to the 32-bit PC= I > + configuration register specified by Address. The value written to the = PCI > + configuration register is returned. This function must guarantee that = all PCI > + read and write operations are serialized. Extra left bits in both AndD= ata and > + OrData are stripped. > + > + If Address > 0x1FFFFFFFF, then ASSERT(). > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > + If StartBit is greater than 31, then ASSERT(). > + If EndBit is greater than 31, then ASSERT(). > + If EndBit is less than StartBit, then ASSERT(). > + If AndData is larger than the bitmask value range specified by StartBi= t and > + EndBit, then ASSERT(). > + If OrData is larger than the bitmask value range specified by StartBit= and > + EndBit, then ASSERT(). > + > + @param [in] Address The PCI configuration register to write. > + @param [in] StartBit The ordinal of the least significant bit in the= bit > + field. Range 0..31. > + @param [in] EndBit The ordinal of the most significant bit in the = bit > + field. Range 0..31. > + @param [in] AndData The value to AND with the PCI configuration reg= ister. > + @param [in] OrData The value to OR with the result of the AND oper= ation. > + > + @return The value written back to the PCI configuration register. > + > +**/ > +UINT32 > +EFIAPI > +PciExpressBitFieldAndThenOr32 ( > + IN UINTN Address, > + IN UINTN StartBit, > + IN UINTN EndBit, > + IN UINT32 AndData, > + IN UINT32 OrData > + ) > +{ > + ASSERT_INVALID_PCI_ADDRESS (Address); > + return MmioBitFieldAndThenOr32 ( > + (UINTN)GetPciExpressAddress (Address), > + StartBit, > + EndBit, > + AndData, > + OrData > + ); > +} > + > +/** > + Reads a range of PCI configuration registers into a caller supplied bu= ffer. > + > + Reads the range of PCI configuration registers specified by StartAddre= ss and > + Size into the buffer specified by Buffer. This function only allows th= e PCI > + configuration registers from a single PCI function to be read. Size is > + returned. When possible 32-bit PCI configuration read cycles are used = to read > + from StartAdress to StartAddress + Size. Due to alignment restrictions= , 8-bit > + and 16-bit PCI configuration read cycles may be used at the beginning = and the > + end of the range. > + > + If StartAddress > 0x1FFFFFFFF, then ASSERT(). > + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT(). > + If Size > 0 and Buffer is NULL, then ASSERT(). > + > + @param [in] StartAddress The starting address that encodes the PCI = Bus, > + Device, Function and Register. > + @param [in] Size The size in bytes of the transfer. > + @param [out] Buffer The pointer to a buffer receiving the data= read. > + > + @return Size read data from StartAddress. > + > +**/ > +UINTN > +EFIAPI > +PciExpressReadBuffer ( > + IN UINTN StartAddress, > + IN UINTN Size, > + OUT VOID *Buffer > + ) > +{ > + UINTN ReturnValue; > + > + ASSERT_INVALID_PCI_ADDRESS (StartAddress); > + ASSERT (((StartAddress & 0xFFF) + Size) <=3D 0x1000); > + > + if (Size =3D=3D 0) { > + return Size; [SAMI] return 0; ? > + } > + > + ASSERT (Buffer !=3D NULL); > + > + // Save Size for return > + ReturnValue =3D Size; > + > + if ((StartAddress & 1) !=3D 0) { > + // Read a byte if StartAddress is byte aligned > + *(volatile UINT8 *)Buffer =3D PciExpressRead8 (StartAddress); > + StartAddress +=3D sizeof (UINT8); > + Size -=3D sizeof (UINT8); > + Buffer =3D (UINT8 *)Buffer + 1; > + } > + > + if ((Size >=3D sizeof (UINT16)) && ((StartAddress & 2) !=3D 0)) { > + // Read a word if StartAddress is word aligned > + WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)PciExpressRead16 (StartA= ddress)); > + > + StartAddress +=3D sizeof (UINT16); > + Size -=3D sizeof (UINT16); > + Buffer =3D (UINT16 *)Buffer + 1; > + } > + > + while (Size >=3D sizeof (UINT32)) { > + // Read as many double words as possible > + WriteUnaligned32 ((UINT32 *)Buffer, (UINT32)PciExpressRead32 (StartA= ddress)); > + > + StartAddress +=3D sizeof (UINT32); > + Size -=3D sizeof (UINT32); > + Buffer =3D (UINT32 *)Buffer + 1; > + } > + > + if (Size >=3D sizeof (UINT16)) { > + // Read the last remaining word if exist > + WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)PciExpressRead16 (StartA= ddress)); > + StartAddress +=3D sizeof (UINT16); > + Size -=3D sizeof (UINT16); > + Buffer =3D (UINT16 *)Buffer + 1; > + } > + > + if (Size >=3D sizeof (UINT8)) { > + // Read the last remaining byte if exist > + *(volatile UINT8 *)Buffer =3D PciExpressRead8 (StartAddress); > + } > + > + return ReturnValue; > +} > + > +/** > + Copies the data in a caller supplied buffer to a specified range of PC= I > + configuration space. > + > + Writes the range of PCI configuration registers specified by StartAddr= ess and > + Size from the buffer specified by Buffer. This function only allows th= e PCI > + configuration registers from a single PCI function to be written. Size= is > + returned. When possible 32-bit PCI configuration write cycles are used= to > + write from StartAdress to StartAddress + Size. Due to alignment restri= ctions, > + 8-bit and 16-bit PCI configuration write cycles may be used at the beg= inning > + and the end of the range. > + > + If StartAddress > 0x1FFFFFFFF, then ASSERT(). > + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT(). > + If Size > 0 and Buffer is NULL, then ASSERT(). > + > + @param [in] StartAddress The starting address that encodes the PCI B= us, > + Device, Function and Register. > + @param [in] Size The size in bytes of the transfer. > + @param [in] Buffer The pointer to a buffer containing the data= to write. > + > + @return Size written to StartAddress. > + > +**/ > +UINTN > +EFIAPI > +PciExpressWriteBuffer ( > + IN UINTN StartAddress, > + IN UINTN Size, > + IN VOID *Buffer > + ) > +{ > + UINTN ReturnValue; > + > + ASSERT_INVALID_PCI_ADDRESS (StartAddress); > + ASSERT (((StartAddress & 0xFFF) + Size) <=3D 0x1000); > + > + if (Size =3D=3D 0) { > + return 0; > + } > + > + ASSERT (Buffer !=3D NULL); > + > + // Save Size for return > + ReturnValue =3D Size; > + > + if ((StartAddress & 1) !=3D 0) { > + // Write a byte if StartAddress is byte aligned > + PciExpressWrite8 (StartAddress, *(UINT8 *)Buffer); > + StartAddress +=3D sizeof (UINT8); > + Size -=3D sizeof (UINT8); > + Buffer =3D (UINT8 *)Buffer + 1; > + } > + > + if ((Size >=3D sizeof (UINT16)) && ((StartAddress & 2) !=3D 0)) { > + // Write a word if StartAddress is word aligned > + PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16 *)Buffer))= ; > + StartAddress +=3D sizeof (UINT16); > + Size -=3D sizeof (UINT16); > + Buffer =3D (UINT16 *)Buffer + 1; > + } > + > + while (Size >=3D sizeof (UINT32)) { > + // Write as many double words as possible > + PciExpressWrite32 (StartAddress, ReadUnaligned32 ((UINT32 *)Buffer))= ; > + StartAddress +=3D sizeof (UINT32); > + Size -=3D sizeof (UINT32); > + Buffer =3D (UINT32 *)Buffer + 1; > + } > + > + if (Size >=3D sizeof (UINT16)) { > + // Write the last remaining word if exist > + PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16 *)Buffer))= ; > + StartAddress +=3D sizeof (UINT16); > + Size -=3D sizeof (UINT16); > + Buffer =3D (UINT16 *)Buffer + 1; > + } > + > + if (Size >=3D sizeof (UINT8)) { > + // Write the last remaining byte if exist > + PciExpressWrite8 (StartAddress, *(UINT8 *)Buffer); > + } > + > + return ReturnValue; > +} > diff --git a/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.uni= b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.uni > new file mode 100644 > index 000000000000..540453d4a189 > --- /dev/null > +++ b/Platform/ARM/Morello/Library/PciExpressLib/PciExpressLib.uni > @@ -0,0 +1,18 @@ > +// /** @file > +// Instance of PCI Express Library using the 256 MB PCI Express MMIO win= dow. > +// > +// PCI Express Library that uses the 256 MB PCI Express MMIO window to p= erform > +// PCI Configuration cycles. Layers on top of an I/O Library instance. > +// > +// Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved. > +// > +// Copyright (c) 2021, ARM Limited. All rights reserved.
> + > +// SPDX-License-Identifier: BSD-2-Clause-Patent > +// > +// **/ > + > + > +#string STR_MODULE_ABSTRACT #language en-US "Instance of PCI= Express Library using the 256 MB PCI Express MMIO window" > + > +#string STR_MODULE_DESCRIPTION #language en-US "PCI Express Lib= rary that uses the 256 MB PCI Express MMIO window to perform PCI Configurat= ion cycles. Layers on top of an I/O Library instance." [SAMI] Does this comment need updating? Same for the file header documentation. IMPORTANT NOTICE: The contents of this email and any attachments are confid= ential and may also be privileged. If you are not the intended recipient, p= lease notify the sender immediately and do not disclose the contents to any= other person, use it for any purpose, or store or copy the information in = any medium. Thank you.