From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 6CBB5AC0B09 for ; Fri, 4 Aug 2023 17:37:52 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=OEhb8V6M+y4TtD9mzpd7ShyG7MmqCua2vUfqOU7RCo8=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1691170671; v=1; b=jpXBVlExHfkShrRe/YPhSl3PhulRt3i0hFz1LY3NQesLty7KzY6szE3F3MmksdTYQ1AGGwQ6 pKdbaLWbjP9gIkbZJlvIwOUMBWFXn3JfqqXc16Q0Eac3oOL78pi09xpedCv5rzWavf+AJXAFoCD y/0BBwF7DevB+PC498LNRZ+8= X-Received: by 127.0.0.2 with SMTP id 0BRsYY7687511xdTaLbCIchf; Fri, 04 Aug 2023 10:37:51 -0700 X-Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by mx.groups.io with SMTP id smtpd.web11.3488.1691170670293648238 for ; Fri, 04 Aug 2023 10:37:50 -0700 X-IronPort-AV: E=McAfee;i="6600,9927,10792"; a="350517500" X-IronPort-AV: E=Sophos;i="6.01,255,1684825200"; d="scan'208";a="350517500" X-Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2023 10:37:43 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10792"; a="730129841" X-IronPort-AV: E=Sophos;i="6.01,255,1684825200"; d="scan'208";a="730129841" X-Received: from fmbiosdev02.amr.corp.intel.com ([10.105.221.44]) by orsmga002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Aug 2023 10:37:42 -0700 From: "Saloni Kasbekar" To: devel@edk2.groups.io Cc: Saloni Kasbekar , Sai Chaganty , Nate DeSimone , Isaac Oram , Rosen Chuang Subject: [edk2-devel] [PATCH v2 1/7] AlderlakeSiliconPkg: Add package and library instances Date: Fri, 4 Aug 2023 10:37:31 -0700 Message-Id: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,saloni.kasbekar@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: pDEasBCa6nLJV7o1cDRBun5Tx7686176AA= Content-Transfer-Encoding: 8bit X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=jpXBVlEx; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=intel.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io Create the AlderlakeSiliconPkg to provide an initial package for silicon initialization code for Alder Lake (ADL) products. Add the following libraries - - BasePciSegmentMultiSegLibPci - BaseSiConfigBlockLib - PeiPostMemSiliconPolicyInitLib - PeiPreMemSiliconPolicyInitLib Cc: Sai Chaganty Cc: Nate DeSimone Cc: Isaac Oram Cc: Rosen Chuang Signed-off-by: Saloni Kasbekar --- .../BasePciSegmentMultiSegLibPci.inf | 37 ++ .../BasePciSegmentMultiSegLibPci.uni | 14 + .../PciSegmentLib.c | 597 ++++++++++++++++++ .../BaseSiConfigBlockLib.c | 87 +++ .../BaseSiConfigBlockLib.inf | 32 + .../PeiPostMemSiliconPolicyInitLib.c | 94 +++ .../PeiPostMemSiliconPolicyInitLib.inf | 36 ++ .../PeiPreMemSiliconPolicyInitLib.c | 98 +++ .../PeiPreMemSiliconPolicyInitLib.inf | 36 ++ 9 files changed, 1031 insertions(+) create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.inf create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.uni create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/PciSegmentLib.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPostMemSiliconPolicyInitLib/PeiPostMemSiliconPolicyInitLib.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPostMemSiliconPolicyInitLib/PeiPostMemSiliconPolicyInitLib.inf create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPreMemSiliconPolicyInitLib/PeiPreMemSiliconPolicyInitLib.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPreMemSiliconPolicyInitLib/PeiPreMemSiliconPolicyInitLib.inf diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.inf b/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.inf new file mode 100644 index 0000000000..f3764d0187 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.inf @@ -0,0 +1,37 @@ +## @file +# Instance of PCI Segment Library based on PCI Library. +# +# PCI Segment Library that layers on top of the PCI Library which only +# supports segment 0 and segment 1 PCI configuration access. +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BasePciSegmentMultiSegLibPci + MODULE_UNI_FILE = BasePciSegmentMultiSegLibPci.uni + FILE_GUID = AC65B409-DF03-466e-8D2B-6FCE1079F0B2 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = PciSegmentLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + PciSegmentLib.c + +[Packages] + MdePkg/MdePkg.dec + AlderlakeSiliconPkg/SiPkg.dec + +[LibraryClasses] + BaseLib + PciLib + DebugLib + PcdLib diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.uni b/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.uni new file mode 100644 index 0000000000..dd8d74bee8 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.uni @@ -0,0 +1,14 @@ +// /** @file +// Instance of PCI Segment Library based on PCI Library. +// +// PCI Segment Library that layers on top of the PCI Library which only +// supports segment 0 and segment 1 PCI configuration access. +// +// Copyright (c) 2022, Intel Corporation. All rights reserved.
+// SPDX-License-Identifier: BSD-2-Clause-Patent +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Instance of PCI Segment Library based on PCI Library." + +#string STR_MODULE_DESCRIPTION #language en-US "PCI Segment Library that layers on top of the PCI Library which only supports segment 0 and segment 1 PCI configuration access." diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/PciSegmentLib.c b/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/PciSegmentLib.c new file mode 100644 index 0000000000..9bcb388016 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/PciSegmentLib.c @@ -0,0 +1,597 @@ +/** @file + PCI Segment Library that layers on top of the PCI Library which only + supports segment 0 and segment 1 PCI configuration access. + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include + +/** + Assert the validity of a PCI Segment address. + A valid PCI Segment address should not contain 1's in bits 28..31 and 33..63 + and the segment should be 0 or 1. + + @param A The address to validate. + @param M Additional bits to assert to be zero. + +**/ +#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \ + ASSERT (((A) & (0xfffffffef0000000ULL | (M))) == 0) + +/** + Convert the PCI Segment library address to PCI library address. + From ICL generation support the multiple segment, and the segment number start from BIT28, + So we convert the Segment Number offset from BIT32 to BIT28 + + @param A The address to convert. +**/ +#define PCI_SEGMENT_TO_PCI_ADDRESS(A) ((UINTN) (UINT32) ((A) | ((RShiftU64 ((A) & BIT32, 4))))) + + + +/** + Reads an 8-bit PCI configuration register. + + Reads and returns the 8-bit PCI configuration register specified by Address. + This function must guarantee that all PCI read and write operations are serialized. + + If any reserved bits in Address are set, then ASSERT(). + + @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register. + + @return The 8-bit PCI configuration register specified by Address. + +**/ +UINT8 +EFIAPI +PciSegmentRead8 ( + IN UINT64 Address + ) +{ + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0); + + return PciRead8 (PCI_SEGMENT_TO_PCI_ADDRESS (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 guarantee that all PCI read and write operations are serialized. + + If any reserved bits in Address are set, then ASSERT(). + + @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register. + @param Value The value to write. + + @return The value written to the PCI configuration register. + +**/ +UINT8 +EFIAPI +PciSegmentWrite8 ( + IN UINT64 Address, + IN UINT8 Value + ) +{ + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0); + + return PciWrite8 (PCI_SEGMENT_TO_PCI_ADDRESS (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, + performs 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 register is returned. + This function must guarantee that all PCI read and write operations are serialized. + + If any reserved bits in Address are set, then ASSERT(). + + @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register. + @param OrData The value to OR with the PCI configuration register. + + @return The value written to the PCI configuration register. + +**/ +UINT8 +EFIAPI +PciSegmentOr8 ( + IN UINT64 Address, + IN UINT8 OrData + ) +{ + return PciWrite8 (PCI_SEGMENT_TO_PCI_ADDRESS (Address), (UINT8) (PciSegmentRead8 (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, + performs 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 returned. + This function must guarantee that all PCI read and write operations are serialized. + If any reserved bits in Address are set, then ASSERT(). + + @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register. + @param AndData The value to AND with the PCI configuration register. + + @return The value written to the PCI configuration register. + +**/ +UINT8 +EFIAPI +PciSegmentAnd8 ( + IN UINT64 Address, + IN UINT8 AndData + ) +{ + return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (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, + performs 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 any reserved bits in Address are set, then ASSERT(). + + @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register. + @param AndData The value to AND with the PCI configuration register. + @param OrData The value to OR with the PCI configuration register. + + @return The value written to the PCI configuration register. + +**/ +UINT8 +EFIAPI +PciSegmentAndThenOr8 ( + IN UINT64 Address, + IN UINT8 AndData, + IN UINT8 OrData + ) +{ + return PciSegmentWrite8 (Address, (UINT8) ((PciSegmentRead8 (Address) & AndData) | OrData)); +} + +/** + Reads a 16-bit PCI configuration register. + + Reads and returns the 16-bit PCI configuration register specified by Address. + This function must guarantee that all PCI read and write operations are serialized. + + If any reserved bits in Address are set, then ASSERT(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register. + + @return The 16-bit PCI configuration register specified by Address. + +**/ +UINT16 +EFIAPI +PciSegmentRead16 ( + IN UINT64 Address + ) +{ + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1); + + return PciRead16 (PCI_SEGMENT_TO_PCI_ADDRESS (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 guarantee that all PCI read and write operations are serialized. + + If any reserved bits in Address are set, then ASSERT(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register. + @param Value The value to write. + + @return The parameter of Value. + +**/ +UINT16 +EFIAPI +PciSegmentWrite16 ( + IN UINT64 Address, + IN UINT16 Value + ) +{ + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1); + + return PciWrite16 (PCI_SEGMENT_TO_PCI_ADDRESS (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, performs 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 register is + returned. This function must guarantee that all PCI read and write operations + are serialized. + + If any reserved bits in Address are set, then ASSERT(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Segment, Bus, Device, Function and + Register. + @param OrData The value to OR with the PCI configuration register. + + @return The value written back to the PCI configuration register. + +**/ +UINT16 +EFIAPI +PciSegmentOr16 ( + IN UINT64 Address, + IN UINT16 OrData + ) +{ + return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) | OrData)); +} + +/** + Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value, + followed a bitwise OR with another 16-bit value. + + Reads the 16-bit PCI configuration register specified by Address, + performs 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 any reserved bits in Address are set, then ASSERT(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register. + @param AndData The value to AND with the PCI configuration register. + @param OrData The value to OR with the PCI configuration register. + + @return The value written to the PCI configuration register. + +**/ +UINT16 +EFIAPI +PciSegmentAndThenOr16 ( + IN UINT64 Address, + IN UINT16 AndData, + IN UINT16 OrData + ) +{ + return PciSegmentWrite16 (Address, (UINT16) ((PciSegmentRead16 (Address) & AndData) | OrData)); +} + +/** + Reads a 32-bit PCI configuration register. + + Reads and returns the 32-bit PCI configuration register specified by Address. + This function must guarantee that all PCI read and write operations are serialized. + + If any reserved bits in Address are set, then ASSERT(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register. + + @return The 32-bit PCI configuration register specified by Address. + +**/ +UINT32 +EFIAPI +PciSegmentRead32 ( + IN UINT64 Address + ) +{ + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3); + + return PciRead32 (PCI_SEGMENT_TO_PCI_ADDRESS (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 guarantee that all PCI read and write operations are serialized. + + If any reserved bits in Address are set, then ASSERT(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register. + @param Value The value to write. + + @return The parameter of Value. + +**/ +UINT32 +EFIAPI +PciSegmentWrite32 ( + IN UINT64 Address, + IN UINT32 Value + ) +{ + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3); + + return PciWrite32 (PCI_SEGMENT_TO_PCI_ADDRESS (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, + performs 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 register is returned. + This function must guarantee that all PCI read and write operations are serialized. + + If any reserved bits in Address are set, then ASSERT(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register. + @param OrData The value to OR with the PCI configuration register. + + @return The value written to the PCI configuration register. + +**/ +UINT32 +EFIAPI +PciSegmentOr32 ( + IN UINT64 Address, + IN UINT32 OrData + ) +{ + return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) | OrData); +} + +/** + Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value, + followed a bitwise OR with another 32-bit value. + + Reads the 32-bit PCI configuration register specified by Address, + performs 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 any reserved bits in Address are set, then ASSERT(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register. + @param AndData The value to AND with the PCI configuration register. + @param OrData The value to OR with the PCI configuration register. + + @return The value written to the PCI configuration register. + +**/ +UINT32 +EFIAPI +PciSegmentAndThenOr32 ( + IN UINT64 Address, + IN UINT32 AndData, + IN UINT32 OrData + ) +{ + return PciSegmentWrite32 (Address, (PciSegmentRead32 (Address) & AndData) | OrData); +} +/** + Reads a range of PCI configuration registers into a caller supplied buffer. + + Reads the range of PCI configuration registers specified by StartAddress and + Size into the buffer specified by Buffer. This function only allows the 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 any reserved bits in StartAddress are set, then ASSERT(). + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT(). + If Size > 0 and Buffer is NULL, then ASSERT(). + + @param StartAddress The starting address that encodes the PCI Segment, Bus, Device, + Function and Register. + @param Size The size in bytes of the transfer. + @param Buffer The pointer to a buffer receiving the data read. + + @return Size + +**/ +UINTN +EFIAPI +PciSegmentReadBuffer ( + IN UINT64 StartAddress, + IN UINTN Size, + OUT VOID *Buffer + ) +{ + UINTN ReturnValue; + + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0); + ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000); + + if (Size == 0) { + return Size; + } + + ASSERT (Buffer != NULL); + if (Buffer == NULL) { + return 0; + } + + // + // Save Size for return + // + ReturnValue = Size; + + if ((StartAddress & BIT0) != 0) { + // + // Read a byte if StartAddress is byte aligned + // + *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress); + StartAddress += sizeof (UINT8); + Size -= sizeof (UINT8); + Buffer = (UINT8*)Buffer + 1; + } + + if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) { + // + // Read a word if StartAddress is word aligned + // + WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress)); + StartAddress += sizeof (UINT16); + Size -= sizeof (UINT16); + Buffer = (UINT16*)Buffer + 1; + } + + while (Size >= sizeof (UINT32)) { + // + // Read as many double words as possible + // + WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress)); + StartAddress += sizeof (UINT32); + Size -= sizeof (UINT32); + Buffer = (UINT32*)Buffer + 1; + } + + if (Size >= sizeof (UINT16)) { + // + // Read the last remaining word if exist + // + WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress)); + StartAddress += sizeof (UINT16); + Size -= sizeof (UINT16); + Buffer = (UINT16*)Buffer + 1; + } + + if (Size >= sizeof (UINT8)) { + // + // Read the last remaining byte if exist + // + *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress); + } + + return ReturnValue; +} + +/** + Copies the data in a caller supplied buffer to a specified range of PCI + configuration space. + + Writes the range of PCI configuration registers specified by StartAddress and + Size from the buffer specified by Buffer. This function only allows the 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 restrictions, + 8-bit and 16-bit PCI configuration write cycles may be used at the beginning + and the end of the range. + + If any reserved bits in StartAddress are set, then ASSERT(). + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT(). + If Size > 0 and Buffer is NULL, then ASSERT(). + + @param StartAddress The starting address that encodes the PCI Segment, Bus, Device, + Function and Register. + @param Size The size in bytes of the transfer. + @param Buffer The pointer to a buffer containing the data to write. + + @return The parameter of Size. + +**/ +UINTN +EFIAPI +PciSegmentWriteBuffer ( + IN UINT64 StartAddress, + IN UINTN Size, + IN VOID *Buffer + ) +{ + UINTN ReturnValue; + + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0); + ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000); + + if (Size == 0) { + return 0; + } + + ASSERT (Buffer != NULL); + if (Buffer == NULL) { + return 0; + } + + // + // Save Size for return + // + ReturnValue = Size; + + if ((StartAddress & BIT0) != 0) { + // + // Write a byte if StartAddress is byte aligned + // + PciSegmentWrite8 (StartAddress, *(UINT8*) Buffer); + StartAddress += sizeof (UINT8); + Size -= sizeof (UINT8); + Buffer = (UINT8*) Buffer + 1; + } + + if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) { + // + // Write a word if StartAddress is word aligned + // + PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer)); + StartAddress += sizeof (UINT16); + Size -= sizeof (UINT16); + Buffer = (UINT16*) Buffer + 1; + } + + while (Size >= sizeof (UINT32)) { + // + // Write as many double words as possible + // + PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer)); + StartAddress += sizeof (UINT32); + Size -= sizeof (UINT32); + Buffer = (UINT32*) Buffer + 1; + } + + if (Size >= sizeof (UINT16)) { + // + // Write the last remaining word if exist + // + PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer)); + StartAddress += sizeof (UINT16); + Size -= sizeof (UINT16); + Buffer = (UINT16*) Buffer + 1; + } + + if (Size >= sizeof (UINT8)) { + // + // Write the last remaining byte if exist + // + PciSegmentWrite8 (StartAddress, *(UINT8*) Buffer); + } + + return ReturnValue; +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c b/Silicon/Intel/AlderlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c new file mode 100644 index 0000000000..93290d8371 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c @@ -0,0 +1,87 @@ +/** @file + This file is BaseSiConfigBlockLib library is used to add config blocks + to config block header. + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include +#include +#include +#include +#include +#include + + +/** + GetComponentConfigBlockTotalSize get config block table total size. + + @param[in] ComponentBlocks Component blocks array + @param[in] TotalBlockCount Number of blocks + + @retval Size of config block table +**/ +UINT16 +EFIAPI +GetComponentConfigBlockTotalSize ( + IN COMPONENT_BLOCK_ENTRY *ComponentBlocks, + IN UINT16 TotalBlockCount + ) +{ + UINT16 TotalBlockSize; + UINT16 BlockCount; + + TotalBlockSize = 0; + for (BlockCount = 0 ; BlockCount < TotalBlockCount; BlockCount++) { + TotalBlockSize += (UINT32) ComponentBlocks[BlockCount].Size; + } + + return TotalBlockSize; +} + +/** + AddComponentConfigBlocks add all config blocks. + + @param[in] ConfigBlockTableAddress The pointer to add config blocks + @param[in] ComponentBlocks Config blocks array + @param[in] TotalBlockCount Number of blocks + + @retval EFI_SUCCESS The policy default is initialized. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer +**/ +EFI_STATUS +EFIAPI +AddComponentConfigBlocks ( + IN VOID *ConfigBlockTableAddress, + IN COMPONENT_BLOCK_ENTRY *ComponentBlocks, + IN UINT16 TotalBlockCount + ) +{ + UINT16 BlockCount; + VOID *ConfigBlockPointer; + CONFIG_BLOCK ConfigBlockBuf; + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + // + // Initialize ConfigBlockPointer to NULL + // + ConfigBlockPointer = NULL; + // + // Loop to identify each config block from ComponentBlocks[] Table and add each of them + // + for (BlockCount = 0; BlockCount < TotalBlockCount; BlockCount++) { + ZeroMem (&ConfigBlockBuf, sizeof (CONFIG_BLOCK)); + CopyMem (&(ConfigBlockBuf.Header.GuidHob.Name), ComponentBlocks[BlockCount].Guid, sizeof (EFI_GUID)); + ConfigBlockBuf.Header.GuidHob.Header.HobLength = ComponentBlocks[BlockCount].Size; + ConfigBlockBuf.Header.Revision = ComponentBlocks[BlockCount].Revision; + ConfigBlockPointer = (VOID *)&ConfigBlockBuf; + Status = AddConfigBlock ((VOID *)ConfigBlockTableAddress, (VOID *)&ConfigBlockPointer); + ASSERT_EFI_ERROR (Status); + if (ComponentBlocks[BlockCount].LoadDefault != NULL) { + ComponentBlocks[BlockCount].LoadDefault (ConfigBlockPointer); + } + } + return Status; +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf b/Silicon/Intel/AlderlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf new file mode 100644 index 0000000000..097095ef0d --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf @@ -0,0 +1,32 @@ +## @file +# Component description file for the BaseSiConfigBlockLib library. +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + + +[Defines] +INF_VERSION = 0x00010017 +BASE_NAME = BaseSiConfigBlockLib +FILE_GUID = 6C068D0F-F48E-48CB-B369-433E507AF4A2 +VERSION_STRING = 1.0 +MODULE_TYPE = BASE +LIBRARY_CLASS = SiConfigBlockLib + + +[LibraryClasses] +DebugLib +IoLib +ConfigBlockLib + + +[Packages] +MdePkg/MdePkg.dec +AlderlakeSiliconPkg/SiPkg.dec + + +[Sources] +BaseSiConfigBlockLib.c + + diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPostMemSiliconPolicyInitLib/PeiPostMemSiliconPolicyInitLib.c b/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPostMemSiliconPolicyInitLib/PeiPostMemSiliconPolicyInitLib.c new file mode 100644 index 0000000000..a9d6c7e265 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPostMemSiliconPolicyInitLib/PeiPostMemSiliconPolicyInitLib.c @@ -0,0 +1,94 @@ +/** @file + This library initialize Silicon Policy for PostMemory. + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include +#include +#include +#include +#include +#include + +/** + Performs silicon post-mem policy initialization. + + The returned data must be used as input data for SiliconPolicyDonePostMem (), + and SiliconPolicyUpdateLib.SiliconPolicyUpdatePostMem (). + + @param[in, out] Policy Pointer to policy. + @return the initialized policy. +**/ +VOID * +EFIAPI +SiliconPolicyInitPostMem ( + IN OUT VOID *Policy + ) +{ + EFI_STATUS Status; + SI_POLICY_PPI *SiPolicyPpi; + PEI_SI_DEFAULT_POLICY_INIT_PPI *PeiSiDefaultPolicyInitPpi; + + DEBUG ((DEBUG_INFO, "Silicon PEI Policy Initialization Start in Post-Memory...\n")); + + ASSERT (Policy == NULL); + SiPolicyPpi = NULL; + PeiSiDefaultPolicyInitPpi = NULL; + + // + // Locate Policy init PPI to install default silicon policy + // + Status = PeiServicesLocatePpi ( + &gSiDefaultPolicyInitPpiGuid, + 0, + NULL, + (VOID **) &PeiSiDefaultPolicyInitPpi + ); + ASSERT_EFI_ERROR (Status); + if (PeiSiDefaultPolicyInitPpi != NULL) { + Status = PeiSiDefaultPolicyInitPpi->PeiPolicyInit (); + ASSERT_EFI_ERROR (Status); + if (Status == EFI_SUCCESS) { + Status = PeiServicesLocatePpi ( + &gSiPolicyPpiGuid, + 0, + NULL, + (VOID **) &SiPolicyPpi + ); + ASSERT_EFI_ERROR (Status); + } + } + + if (SiPolicyPpi == NULL) { + DEBUG ((DEBUG_ERROR, "Fail to create default policy!\n")); + return NULL; + } + + + return SiPolicyPpi; +} + +/** + The silicon post-mem policy is finalized. + Silicon code can do initialization based upon the policy data. + + The input Policy must be returned by SiliconPolicyInitPostMem(). + + @param[in] Policy Pointer to policy. + @retval RETURN_SUCCESS The policy is handled consumed by silicon code. +**/ +RETURN_STATUS +EFIAPI +SiliconPolicyDonePostMem ( + IN VOID *Policy + ) +{ + EFI_STATUS Status; + + Status = SiInstallPolicyReadyPpi (); + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_INFO, "Silicon PEI Policy Initialization Done in Post-Memory\n")); + + return Status; +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPostMemSiliconPolicyInitLib/PeiPostMemSiliconPolicyInitLib.inf b/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPostMemSiliconPolicyInitLib/PeiPostMemSiliconPolicyInitLib.inf new file mode 100644 index 0000000000..b13d63d337 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPostMemSiliconPolicyInitLib/PeiPostMemSiliconPolicyInitLib.inf @@ -0,0 +1,36 @@ +## @file +# Component information file for Silicon Policy Init Library +# This library implements Silicon Policy Initialization for PostMemory. +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiPostMemSiliconPolicyInitLib + FILE_GUID = 20B51FFB-93D3-4546-9F13-2C91AEEF9212 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = SiliconPolicyInitLib + +[LibraryClasses] + BaseLib + PcdLib + PeiServicesLib + DebugLib + SiPolicyLib + +[Packages] + MdePkg/MdePkg.dec + AlderlakeSiliconPkg/SiPkg.dec + +[Sources] + PeiPostMemSiliconPolicyInitLib.c + +[Ppis] + gSiDefaultPolicyInitPpiGuid + gEfiPeiMpServicesPpiGuid + +[Depex] + gSiDefaultPolicyInitPpiGuid diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPreMemSiliconPolicyInitLib/PeiPreMemSiliconPolicyInitLib.c b/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPreMemSiliconPolicyInitLib/PeiPreMemSiliconPolicyInitLib.c new file mode 100644 index 0000000000..74fb47a73d --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPreMemSiliconPolicyInitLib/PeiPreMemSiliconPolicyInitLib.c @@ -0,0 +1,98 @@ +/** @file + This library initialize Silicon Policy for PreMemory. + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include +#include +#include +#include +#include + + +/** + Performs silicon pre-mem policy initialization. + + The returned data must be used as input data for SiliconPolicyDonePreMem (), + and SiliconPolicyUpdateLib.SiliconPolicyUpdatePreMem (). + + @param[in, out] Policy Pointer to policy. + @return the initialized policy. +**/ +VOID * +EFIAPI +SiliconPolicyInitPreMem ( + IN OUT VOID *Policy + ) +{ + EFI_STATUS Status; + SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi; + PEI_PREMEM_SI_DEFAULT_POLICY_INIT_PPI *PeiPreMemSiDefaultPolicyInitPpi; + + DEBUG ((DEBUG_INFO, "Silicon PEI Policy Initialization Start in Pre-Memory...\n")); + + ASSERT (Policy == NULL); + SiPreMemPolicyPpi = NULL; + PeiPreMemSiDefaultPolicyInitPpi = NULL; + + // + // Locate Policy init PPI to install default silicon policy + // + Status = PeiServicesLocatePpi ( + &gSiPreMemDefaultPolicyInitPpiGuid, + 0, + NULL, + (VOID **) &PeiPreMemSiDefaultPolicyInitPpi + ); + ASSERT_EFI_ERROR (Status); + if (PeiPreMemSiDefaultPolicyInitPpi != NULL) { + Status = PeiPreMemSiDefaultPolicyInitPpi->PeiPreMemPolicyInit (); + ASSERT_EFI_ERROR (Status); + if (Status == EFI_SUCCESS) { + Status = PeiServicesLocatePpi ( + &gSiPreMemPolicyPpiGuid, + 0, + NULL, + (VOID **) &SiPreMemPolicyPpi + ); + ASSERT_EFI_ERROR (Status); + } + } + + if (SiPreMemPolicyPpi == NULL) { + DEBUG ((DEBUG_ERROR, "Fail to create default policy!\n")); + return NULL; + } + + return SiPreMemPolicyPpi; +} + +/** + The silicon pre-mem policy is finalized. + Silicon code can do initialization based upon the policy data. + + The input Policy must be returned by SiliconPolicyInitPreMem(). + + @param[in] Policy Pointer to policy. + @retval RETURN_SUCCESS The policy is handled consumed by silicon code. +**/ +RETURN_STATUS +EFIAPI +SiliconPolicyDonePreMem ( + IN VOID *Policy + ) +{ + EFI_STATUS Status; + // + // Install PreMem Policy Ready PPI + // While installs PreMemPolicyReadyPpi, RC assumes the Policy is ready and finalized. So please + // update and override any setting before calling this function. + // + Status = SiPreMemInstallPolicyReadyPpi (); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, "Silicon PEI Policy Initialization Done in Pre-Memory\n")); + + return Status; +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPreMemSiliconPolicyInitLib/PeiPreMemSiliconPolicyInitLib.inf b/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPreMemSiliconPolicyInitLib/PeiPreMemSiliconPolicyInitLib.inf new file mode 100644 index 0000000000..d5ce714ce5 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/Library/PeiPreMemSiliconPolicyInitLib/PeiPreMemSiliconPolicyInitLib.inf @@ -0,0 +1,36 @@ +## @file +# Component information file for Silicon Policy Init Library +# This library implements Silicon Policy Initialization for PreMemory. +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiPreMemSiliconPolicyInitLib + FILE_GUID = 1FB4B175-0BB6-4137-A4AC-EA48FCE83862 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = SiliconPolicyInitLib + +[LibraryClasses] + BaseLib + PeiServicesLib + DebugLib + SiPolicyLib + +[Packages] + MdePkg/MdePkg.dec + AlderlakeSiliconPkg/SiPkg.dec + +[Sources] + PeiPreMemSiliconPolicyInitLib.c + +[Pcd] + +[Ppis] + gSiPreMemDefaultPolicyInitPpiGuid + +[Depex] + gSiPreMemDefaultPolicyInitPpiGuid -- 2.36.1.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#107568): https://edk2.groups.io/g/devel/message/107568 Mute This Topic: https://groups.io/mt/100551000/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-