aboutsummaryrefslogtreecommitdiffstats
path: root/roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei
diff options
context:
space:
mode:
Diffstat (limited to 'roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei')
-rw-r--r--roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf50
-rw-r--r--roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.uni17
-rw-r--r--roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2PeiExtra.uni14
-rw-r--r--roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PciCfg2.c311
4 files changed, 392 insertions, 0 deletions
diff --git a/roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf b/roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf
new file mode 100644
index 000000000..94665213d
--- /dev/null
+++ b/roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf
@@ -0,0 +1,50 @@
+## @file
+# Pcat SingleSegmentPciCfg2Pei Pei Module.
+#
+# It installs SingleSegmentPciConfiguration2 PPI to provide read, write and modify access to Pci configuration space in PEI phase.
+# To follow PI specification, these services also support access to the unaligned Pci address.
+#
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PcatSingleSegmentPciCfg2Pei
+ MODULE_UNI_FILE = PcatSingleSegmentPciCfg2Pei.uni
+ FILE_GUID = 4F1F379F-2A62-48bb-AC34-D3F135C6E2B7
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PeimInitializePciCfg
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC (EBC is for build only)
+#
+
+[Sources]
+ PciCfg2.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+
+[LibraryClasses]
+ PeimEntryPoint
+ PciLib
+ BaseLib
+ DebugLib
+ PeiServicesLib
+
+[Ppis]
+ gEfiPciCfg2PpiGuid ## PRODUCES
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ PcatSingleSegmentPciCfg2PeiExtra.uni
diff --git a/roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.uni b/roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.uni
new file mode 100644
index 000000000..78a7a7836
--- /dev/null
+++ b/roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.uni
@@ -0,0 +1,17 @@
+// /** @file
+// Pcat SingleSegmentPciCfg2Pei Pei Module.
+//
+// It installs SingleSegmentPciConfiguration2 PPI to provide read, write and modify access to Pci configuration space in PEI phase.
+// To follow PI specification, these services also support access to the unaligned Pci address.
+//
+// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Pcat SingleSegmentPciCfg2Pei Pei Module."
+
+#string STR_MODULE_DESCRIPTION #language en-US "It installs SingleSegmentPciConfiguration2 PPI to provide read, write, and modify access to PCI configuration space in the PEI phase. These services also support access to the unaligned PCI address."
+
diff --git a/roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2PeiExtra.uni b/roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2PeiExtra.uni
new file mode 100644
index 000000000..8b0dd5f73
--- /dev/null
+++ b/roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2PeiExtra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// PcatSingleSegmentPciCfg2Pei Localized Strings and Content
+//
+// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Single Segment PCI Configuration PEI Module"
+
+
diff --git a/roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PciCfg2.c b/roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PciCfg2.c
new file mode 100644
index 000000000..41fa92911
--- /dev/null
+++ b/roms/edk2/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PciCfg2.c
@@ -0,0 +1,311 @@
+/** @file
+ This driver installs Single Segment Pci Configuration 2 PPI
+ to provide read, write and modify access to Pci configuration space in PEI phase.
+ To follow PI specification, these services also support access to the unaligned Pci address.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Ppi/PciCfg2.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <IndustryStandard/Pci.h>
+
+/**
+ Convert EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS to PCI_LIB_ADDRESS.
+
+ @param Address PCI address with EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS format.
+
+ @return PCI address with PCI_LIB_ADDRESS format.
+
+**/
+UINTN
+PciCfgAddressConvert (
+ EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *Address
+ )
+{
+ if (Address->ExtendedRegister == 0) {
+ return PCI_LIB_ADDRESS (Address->Bus, Address->Device, Address->Function, Address->Register);
+ }
+
+ return PCI_LIB_ADDRESS (Address->Bus, Address->Device, Address->Function, Address->ExtendedRegister);
+}
+
+/**
+ Reads from a given location in the PCI configuration space.
+
+ @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.
+ @param This Pointer to local data for the interface.
+ @param Width The width of the access. Enumerated in bytes.
+ See EFI_PEI_PCI_CFG_PPI_WIDTH above.
+ @param Address The physical address of the access. The format of
+ the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.
+ @param Buffer A pointer to the buffer of data.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER The invalid access width.
+
+**/
+EFI_STATUS
+EFIAPI
+PciCfg2Read (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PCI_CFG2_PPI *This,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN OUT VOID *Buffer
+ )
+{
+ UINTN PciLibAddress;
+
+ PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);
+
+ if (Width == EfiPeiPciCfgWidthUint8) {
+ *((UINT8 *) Buffer) = PciRead8 (PciLibAddress);
+ } else if (Width == EfiPeiPciCfgWidthUint16) {
+ if ((PciLibAddress & 0x01) == 0) {
+ //
+ // Aligned Pci address access
+ //
+ WriteUnaligned16 (((UINT16 *) Buffer), PciRead16 (PciLibAddress));
+ } else {
+ //
+ // Unaligned Pci address access, break up the request into byte by byte.
+ //
+ *((UINT8 *) Buffer) = PciRead8 (PciLibAddress);
+ *((UINT8 *) Buffer + 1) = PciRead8 (PciLibAddress + 1);
+ }
+ } else if (Width == EfiPeiPciCfgWidthUint32) {
+ if ((PciLibAddress & 0x03) == 0) {
+ //
+ // Aligned Pci address access
+ //
+ WriteUnaligned32 (((UINT32 *) Buffer), PciRead32 (PciLibAddress));
+ } else if ((PciLibAddress & 0x01) == 0) {
+ //
+ // Unaligned Pci address access, break up the request into word by word.
+ //
+ WriteUnaligned16 (((UINT16 *) Buffer), PciRead16 (PciLibAddress));
+ WriteUnaligned16 (((UINT16 *) Buffer + 1), PciRead16 (PciLibAddress + 2));
+ } else {
+ //
+ // Unaligned Pci address access, break up the request into byte by byte.
+ //
+ *((UINT8 *) Buffer) = PciRead8 (PciLibAddress);
+ *((UINT8 *) Buffer + 1) = PciRead8 (PciLibAddress + 1);
+ *((UINT8 *) Buffer + 2) = PciRead8 (PciLibAddress + 2);
+ *((UINT8 *) Buffer + 3) = PciRead8 (PciLibAddress + 3);
+ }
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Write to a given location in the PCI configuration space.
+
+ @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation.
+ @param This Pointer to local data for the interface.
+ @param Width The width of the access. Enumerated in bytes.
+ See EFI_PEI_PCI_CFG_PPI_WIDTH above.
+ @param Address The physical address of the access. The format of
+ the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.
+ @param Buffer A pointer to the buffer of data.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER The invalid access width.
+
+**/
+EFI_STATUS
+EFIAPI
+PciCfg2Write (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PCI_CFG2_PPI *This,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN OUT VOID *Buffer
+ )
+{
+ UINTN PciLibAddress;
+
+ PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);
+
+ if (Width == EfiPeiPciCfgWidthUint8) {
+ PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));
+ } else if (Width == EfiPeiPciCfgWidthUint16) {
+ if ((PciLibAddress & 0x01) == 0) {
+ //
+ // Aligned Pci address access
+ //
+ PciWrite16 (PciLibAddress, ReadUnaligned16 ((UINT16 *) Buffer));
+ } else {
+ //
+ // Unaligned Pci address access, break up the request into byte by byte.
+ //
+ PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));
+ PciWrite8 (PciLibAddress + 1, *((UINT8 *) Buffer + 1));
+ }
+ } else if (Width == EfiPeiPciCfgWidthUint32) {
+ if ((PciLibAddress & 0x03) == 0) {
+ //
+ // Aligned Pci address access
+ //
+ PciWrite32 (PciLibAddress, ReadUnaligned32 ((UINT32 *) Buffer));
+ } else if ((PciLibAddress & 0x01) == 0) {
+ //
+ // Unaligned Pci address access, break up the request into word by word.
+ //
+ PciWrite16 (PciLibAddress, ReadUnaligned16 ((UINT16 *) Buffer));
+ PciWrite16 (PciLibAddress + 2, ReadUnaligned16 ((UINT16 *) Buffer + 1));
+ } else {
+ //
+ // Unaligned Pci address access, break up the request into byte by byte.
+ //
+ PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));
+ PciWrite8 (PciLibAddress + 1, *((UINT8 *) Buffer + 1));
+ PciWrite8 (PciLibAddress + 2, *((UINT8 *) Buffer + 2));
+ PciWrite8 (PciLibAddress + 3, *((UINT8 *) Buffer + 3));
+ }
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function performs a read-modify-write operation on the contents from a given
+ location in the PCI configuration space.
+
+ @param PeiServices An indirect pointer to the PEI Services Table
+ published by the PEI Foundation.
+ @param This Pointer to local data for the interface.
+ @param Width The width of the access. Enumerated in bytes. Type
+ EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().
+ @param Address The physical address of the access.
+ @param SetBits Points to value to bitwise-OR with the read configuration value.
+ The size of the value is determined by Width.
+ @param ClearBits Points to the value to negate and bitwise-AND with the read configuration value.
+ The size of the value is determined by Width.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER The invalid access width.
+
+**/
+EFI_STATUS
+EFIAPI
+PciCfg2Modify (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PCI_CFG2_PPI *This,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN VOID *SetBits,
+ IN VOID *ClearBits
+ )
+{
+ UINTN PciLibAddress;
+ UINT16 ClearValue16;
+ UINT16 SetValue16;
+ UINT32 ClearValue32;
+ UINT32 SetValue32;
+
+ PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);
+
+ if (Width == EfiPeiPciCfgWidthUint8) {
+ PciAndThenOr8 (PciLibAddress, (UINT8) (~(*(UINT8 *) ClearBits)), *((UINT8 *) SetBits));
+ } else if (Width == EfiPeiPciCfgWidthUint16) {
+ if ((PciLibAddress & 0x01) == 0) {
+ //
+ // Aligned Pci address access
+ //
+ ClearValue16 = (UINT16) (~ReadUnaligned16 ((UINT16 *) ClearBits));
+ SetValue16 = ReadUnaligned16 ((UINT16 *) SetBits);
+ PciAndThenOr16 (PciLibAddress, ClearValue16, SetValue16);
+ } else {
+ //
+ // Unaligned Pci address access, break up the request into byte by byte.
+ //
+ PciAndThenOr8 (PciLibAddress, (UINT8) (~(*(UINT8 *) ClearBits)), *((UINT8 *) SetBits));
+ PciAndThenOr8 (PciLibAddress + 1, (UINT8) (~(*((UINT8 *) ClearBits + 1))), *((UINT8 *) SetBits + 1));
+ }
+ } else if (Width == EfiPeiPciCfgWidthUint32) {
+ if ((PciLibAddress & 0x03) == 0) {
+ //
+ // Aligned Pci address access
+ //
+ ClearValue32 = (UINT32) (~ReadUnaligned32 ((UINT32 *) ClearBits));
+ SetValue32 = ReadUnaligned32 ((UINT32 *) SetBits);
+ PciAndThenOr32 (PciLibAddress, ClearValue32, SetValue32);
+ } else if ((PciLibAddress & 0x01) == 0) {
+ //
+ // Unaligned Pci address access, break up the request into word by word.
+ //
+ ClearValue16 = (UINT16) (~ReadUnaligned16 ((UINT16 *) ClearBits));
+ SetValue16 = ReadUnaligned16 ((UINT16 *) SetBits);
+ PciAndThenOr16 (PciLibAddress, ClearValue16, SetValue16);
+
+ ClearValue16 = (UINT16) (~ReadUnaligned16 ((UINT16 *) ClearBits + 1));
+ SetValue16 = ReadUnaligned16 ((UINT16 *) SetBits + 1);
+ PciAndThenOr16 (PciLibAddress + 2, ClearValue16, SetValue16);
+ } else {
+ //
+ // Unaligned Pci address access, break up the request into byte by byte.
+ //
+ PciAndThenOr8 (PciLibAddress, (UINT8) (~(*(UINT8 *) ClearBits)), *((UINT8 *) SetBits));
+ PciAndThenOr8 (PciLibAddress + 1, (UINT8) (~(*((UINT8 *) ClearBits + 1))), *((UINT8 *) SetBits + 1));
+ PciAndThenOr8 (PciLibAddress + 2, (UINT8) (~(*((UINT8 *) ClearBits + 2))), *((UINT8 *) SetBits + 2));
+ PciAndThenOr8 (PciLibAddress + 3, (UINT8) (~(*((UINT8 *) ClearBits + 3))), *((UINT8 *) SetBits + 3));
+ }
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_PEI_PCI_CFG2_PPI gPciCfg2Ppi = {
+ PciCfg2Read,
+ PciCfg2Write,
+ PciCfg2Modify,
+ 0
+};
+
+EFI_PEI_PPI_DESCRIPTOR gPciCfg2PpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPciCfg2PpiGuid,
+ &gPciCfg2Ppi
+};
+
+/**
+ Module's entry function.
+ This routine will install EFI_PEI_PCI_CFG2_PPI.
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+
+ @return Whether success to install service.
+**/
+EFI_STATUS
+EFIAPI
+PeimInitializePciCfg (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ (**(EFI_PEI_SERVICES **)PeiServices).PciCfg = &gPciCfg2Ppi;
+ Status = PeiServicesInstallPpi (&gPciCfg2PpiList);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}