]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PciCfg2.c
1) Add PcatSingleSegmentPciCfg2Pei in MdeModulePkg.
[mirror_edk2.git] / MdeModulePkg / Universal / PcatSingleSegmentPciCfg2Pei / PciCfg2.c
diff --git a/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PciCfg2.c b/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PciCfg2.c
new file mode 100644 (file)
index 0000000..cab5512
--- /dev/null
@@ -0,0 +1,348 @@
+/**\r
+\r
+  Copyright (c) 2006 - 2007, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+\r
+#include <Ppi/PciCfg2.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PciLib.h>\r
+#include <Library/PeimEntryPoint.h>\r
+\r
+#include <IndustryStandard\Pci.h>\r
+\r
+#define COMMON_TO_PCILIB_ADDRESS(A) (UINTN)PCI_LIB_ADDRESS( \\r
+       ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &A)->Bus, \\r
+       ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &A)->Device, \\r
+       ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &A)->Function, \\r
+       ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &A)->Register \\r
+       )\r
+\r
+\r
+/**\r
+  Reads from a given location in the PCI configuration space.\r
+\r
+  @param  PeiServices     An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
+\r
+  @param  This            Pointer to local data for the interface.\r
+\r
+  @param  Width           The width of the access. Enumerated in bytes.\r
+                          See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
+\r
+  @param  Address         The physical address of the access. The format of\r
+                          the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
+\r
+  @param  Buffer          A pointer to the buffer of data..\r
+\r
+\r
+  @retval EFI_SUCCESS           The function completed successfully.\r
+\r
+  @retval EFI_DEVICE_ERROR      There was a problem with the transaction.\r
+\r
+  @retval EFI_DEVICE_NOT_READY  The device is not capable of supporting the operation at this\r
+                                time.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI \r
+PciCfg2Read (\r
+  IN CONST  EFI_PEI_SERVICES          **PeiServices,\r
+  IN CONST  EFI_PEI_PCI_CFG2_PPI      *This,\r
+  IN        EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
+  IN        UINT64                    Address,\r
+  IN OUT    VOID                      *Buffer\r
+);\r
+\r
+/**\r
+  Write to a given location in the PCI configuration space.\r
+\r
+  @param  PeiServices     An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
+\r
+  @param  This            Pointer to local data for the interface.\r
+\r
+  @param  Width           The width of the access. Enumerated in bytes.\r
+                          See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
+\r
+  @param  Address         The physical address of the access. The format of\r
+                          the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
+\r
+  @param  Buffer          A pointer to the buffer of data..\r
+\r
+\r
+  @retval EFI_SUCCESS           The function completed successfully.\r
+\r
+  @retval EFI_DEVICE_ERROR      There was a problem with the transaction.\r
+\r
+  @retval EFI_DEVICE_NOT_READY  The device is not capable of supporting the operation at this\r
+                                time.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI \r
+PciCfg2Write (\r
+  IN CONST  EFI_PEI_SERVICES          **PeiServices,\r
+  IN CONST  EFI_PEI_PCI_CFG2_PPI      *This,\r
+  IN        EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
+  IN        UINT64                    Address,\r
+  IN OUT    VOID                      *Buffer\r
+);\r
+\r
+\r
+/**\r
+  PCI read-modify-write operation.\r
+\r
+  @param  PeiServices     An indirect pointer to the PEI Services Table\r
+                          published by the PEI Foundation.\r
+\r
+  @param  This            Pointer to local data for the interface.\r
+\r
+  @param  Width           The width of the access. Enumerated in bytes. Type\r
+                          EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().\r
+\r
+  @param  Address         The physical address of the access.\r
+\r
+  @param  SetBits         Points to value to bitwise-OR with the read configuration value.\r
+\r
+                          The size of the value is determined by Width.\r
+\r
+  @param  ClearBits       Points to the value to negate and bitwise-AND with the read configuration value.\r
+                          The size of the value is determined by Width.\r
+\r
+\r
+  @retval EFI_SUCCESS           The function completed successfully.\r
+\r
+  @retval EFI_DEVICE_ERROR      There was a problem with the transaction.\r
+\r
+  @retval EFI_DEVICE_NOT_READY  The device is not capable of supporting\r
+                                the operation at this time.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI \r
+PciCfg2Modify (\r
+  IN CONST  EFI_PEI_SERVICES          **PeiServices,\r
+  IN CONST  EFI_PEI_PCI_CFG2_PPI      *This,\r
+  IN        EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
+  IN        UINT64                    Address,\r
+  IN CONST  VOID                      *SetBits,\r
+  IN CONST  VOID                      *ClearBits\r
+);\r
+\r
+\r
+\r
+/**\r
+  @par Ppi Description:\r
+  The EFI_PEI_PCI_CFG2_PPI interfaces are used to abstract\r
+  accesses to PCI controllers behind a PCI root bridge\r
+  controller.\r
+\r
+  @param Read     PCI read services.  See the Read() function description.\r
+\r
+  @param Write    PCI write services.  See the Write() function description.\r
+\r
+  @param Modify   PCI read-modify-write services.  See the Modify() function description.\r
+\r
+  @param Segment  The PCI bus segment which the specified functions will access.\r
+\r
+**/\r
+GLOBAL_REMOVE_IF_UNREFERENCED\r
+EFI_PEI_PCI_CFG2_PPI gPciCfg2Ppi = {\r
+  PciCfg2Read,\r
+  PciCfg2Write,\r
+  PciCfg2Modify\r
+};\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED\r
+EFI_PEI_PPI_DESCRIPTOR gPciCfg2PpiList = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gEfiPciCfg2PpiGuid,\r
+  &gPciCfg2Ppi\r
+};\r
+\r
+/**\r
+  Reads from a given location in the PCI configuration space.\r
+\r
+  @param  PeiServices     An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
+\r
+  @param  This            Pointer to local data for the interface.\r
+\r
+  @param  Width           The width of the access. Enumerated in bytes.\r
+                          See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
+\r
+  @param  Address         The physical address of the access. The format of\r
+                          the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
+\r
+  @param  Buffer          A pointer to the buffer of data..\r
+\r
+\r
+  @retval EFI_SUCCESS           The function completed successfully.\r
+\r
+  @retval EFI_DEVICE_ERROR      There was a problem with the transaction.\r
+\r
+  @retval EFI_DEVICE_NOT_READY  The device is not capable of supporting the operation at this\r
+                                time.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI \r
+PciCfg2Read (\r
+  IN CONST  EFI_PEI_SERVICES          **PeiServices,\r
+  IN CONST  EFI_PEI_PCI_CFG2_PPI      *This,\r
+  IN        EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
+  IN        UINT64                    Address,\r
+  IN OUT    VOID                      *Buffer\r
+)\r
+{\r
+  UINTN  PciLibAddress;\r
+\r
+  PciLibAddress = COMMON_TO_PCILIB_ADDRESS (Address);\r
+\r
+  if (Width == EfiPeiPciCfgWidthUint8) {\r
+    *((UINT8 *) Buffer) = PciRead8 (PciLibAddress);\r
+  } else if (Width == EfiPeiPciCfgWidthUint16) {\r
+    *((UINT16 *) Buffer) = PciRead16 (PciLibAddress);\r
+  } else if (Width == EfiPeiPciCfgWidthUint32) {\r
+    *((UINT32 *) Buffer) = PciRead32 (PciLibAddress);\r
+  } else {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Write to a given location in the PCI configuration space.\r
+\r
+  @param  PeiServices     An indirect pointer to the PEI Services Table published by the PEI Foundation.\r
+\r
+  @param  This            Pointer to local data for the interface.\r
+\r
+  @param  Width           The width of the access. Enumerated in bytes.\r
+                          See EFI_PEI_PCI_CFG_PPI_WIDTH above.\r
+\r
+  @param  Address         The physical address of the access. The format of\r
+                          the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS.\r
+\r
+  @param  Buffer          A pointer to the buffer of data..\r
+\r
+\r
+  @retval EFI_SUCCESS           The function completed successfully.\r
+\r
+  @retval EFI_DEVICE_ERROR      There was a problem with the transaction.\r
+\r
+  @retval EFI_DEVICE_NOT_READY  The device is not capable of supporting the operation at this\r
+                                time.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI \r
+PciCfg2Write (\r
+  IN CONST  EFI_PEI_SERVICES          **PeiServices,\r
+  IN CONST  EFI_PEI_PCI_CFG2_PPI      *This,\r
+  IN        EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
+  IN        UINT64                    Address,\r
+  IN OUT    VOID                      *Buffer\r
+)\r
+{\r
+  UINTN  PciLibAddress;\r
+\r
+  PciLibAddress = COMMON_TO_PCILIB_ADDRESS (Address);\r
+\r
+  if (Width == EfiPeiPciCfgWidthUint8) {\r
+    PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));\r
+  } else if (Width == EfiPeiPciCfgWidthUint16) {\r
+    PciWrite16 (PciLibAddress, *((UINT16 *) Buffer));\r
+  } else if (Width == EfiPeiPciCfgWidthUint32) {\r
+    PciWrite32 (PciLibAddress, *((UINT32 *) Buffer));\r
+  } else {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  PCI read-modify-write operation.\r
+\r
+  @param  PeiServices     An indirect pointer to the PEI Services Table\r
+                          published by the PEI Foundation.\r
+\r
+  @param  This            Pointer to local data for the interface.\r
+\r
+  @param  Width           The width of the access. Enumerated in bytes. Type\r
+                          EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().\r
+\r
+  @param  Address         The physical address of the access.\r
+\r
+  @param  SetBits         Points to value to bitwise-OR with the read configuration value.\r
+\r
+                          The size of the value is determined by Width.\r
+\r
+  @param  ClearBits       Points to the value to negate and bitwise-AND with the read configuration value.\r
+                          The size of the value is determined by Width.\r
+\r
+\r
+  @retval EFI_SUCCESS           The function completed successfully.\r
+\r
+  @retval EFI_DEVICE_ERROR      There was a problem with the transaction.\r
+\r
+  @retval EFI_DEVICE_NOT_READY  The device is not capable of supporting\r
+                                the operation at this time.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI \r
+PciCfg2Modify (\r
+  IN CONST  EFI_PEI_SERVICES          **PeiServices,\r
+  IN CONST  EFI_PEI_PCI_CFG2_PPI      *This,\r
+  IN        EFI_PEI_PCI_CFG_PPI_WIDTH Width,\r
+  IN        UINT64                    Address,\r
+  IN CONST  VOID                      *SetBits,\r
+  IN CONST  VOID                      *ClearBits\r
+)\r
+{\r
+  UINTN  PciLibAddress;\r
+\r
+  PciLibAddress = COMMON_TO_PCILIB_ADDRESS (Address);\r
+\r
+  if (Width == EfiPeiPciCfgWidthUint8) {\r
+    PciAndThenOr8 (PciLibAddress, ~(*(UINT8 *)ClearBits), *((UINT8 *) SetBits));\r
+  } else if (Width == EfiPeiPciCfgWidthUint16) {\r
+    PciAndThenOr16 (PciLibAddress, ~ReadUnaligned16 ((UINT16 *) ClearBits), ReadUnaligned16 ((UINT16 *) SetBits));\r
+  } else if (Width == EfiPeiPciCfgWidthUint32) {\r
+    PciAndThenOr32 (PciLibAddress, ~ReadUnaligned32 ((UINT32 *) ClearBits), ReadUnaligned32 ((UINT32 *) SetBits));\r
+  } else {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeimInitializePciCfg (\r
+  IN EFI_FFS_FILE_HEADER       *FfsHeader,\r
+  IN EFI_PEI_SERVICES          **PeiServices\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+\r
+  ASSERT ((**PeiServices).Hdr.Revision >= PEI_SERVICES_REVISION);\r
+\r
+  (**PeiServices).PciCfg = &gPciCfg2Ppi;\r
+  Status = (**PeiServices).InstallPpi (PeiServices, &gPciCfg2PpiList);\r
+\r
+  return Status;\r
+}\r