]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add ESAL support libraries to MdePkg
authormdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 10 Jun 2011 18:58:08 +0000 (18:58 +0000)
committermdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 10 Jun 2011 18:58:08 +0000 (18:58 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11784 6f19259b-4bc3-4df7-8a09-765794883524

24 files changed:
MdePkg/Include/Library/ExtendedSalLib.h [new file with mode: 0644]
MdePkg/Library/DxeExtendedSalLib/DxeExtendedSalLib.inf [new file with mode: 0644]
MdePkg/Library/DxeExtendedSalLib/ExtendedSalLib.c [new file with mode: 0644]
MdePkg/Library/DxeExtendedSalLib/Ipf/AsmExtendedSalLib.s [new file with mode: 0644]
MdePkg/Library/DxeIoLibEsal/DxeIoLibEsal.inf [new file with mode: 0644]
MdePkg/Library/DxeIoLibEsal/DxeIoLibEsalInternal.h [new file with mode: 0644]
MdePkg/Library/DxeIoLibEsal/IoHighLevel.c [new file with mode: 0644]
MdePkg/Library/DxeIoLibEsal/IoLib.c [new file with mode: 0644]
MdePkg/Library/DxeIoLibEsal/IoLibMmioBuffer.c [new file with mode: 0644]
MdePkg/Library/DxePalLibEsal/DxePalLibEsal.c [new file with mode: 0644]
MdePkg/Library/DxePalLibEsal/DxePalLibEsal.inf [new file with mode: 0644]
MdePkg/Library/DxePciLibEsal/DxePciLibEsal.inf [new file with mode: 0644]
MdePkg/Library/DxePciLibEsal/PciLib.c [new file with mode: 0644]
MdePkg/Library/DxePciSegmentLibEsal/DxePciSegmentLibEsal.inf [new file with mode: 0644]
MdePkg/Library/DxePciSegmentLibEsal/PciLib.c [new file with mode: 0644]
MdePkg/Library/DxeRuntimeExtendedSalLib/DxeRuntimeExtendedSalLib.inf [new file with mode: 0644]
MdePkg/Library/DxeRuntimeExtendedSalLib/ExtendedSalLib.c [new file with mode: 0644]
MdePkg/Library/DxeRuntimeExtendedSalLib/Ipf/AsmExtendedSalLib.s [new file with mode: 0644]
MdePkg/Library/DxeSalLibEsal/DxeSalLibEsal.c [new file with mode: 0644]
MdePkg/Library/DxeSalLibEsal/DxeSalLibEsal.inf [new file with mode: 0644]
MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.c [new file with mode: 0644]
MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.inf [new file with mode: 0644]
MdePkg/MdePkg.dec
MdePkg/MdePkg.dsc

diff --git a/MdePkg/Include/Library/ExtendedSalLib.h b/MdePkg/Include/Library/ExtendedSalLib.h
new file mode 100644 (file)
index 0000000..6f28eeb
--- /dev/null
@@ -0,0 +1,494 @@
+/** @file\r
+  Library class definition of Extended SAL Library.\r
+\r
+Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+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
+#ifndef _EXTENDED_SAL_LIB_H__\r
+#define _EXTENDED_SAL_LIB_H__\r
+\r
+#include <IndustryStandard/Sal.h>\r
+\r
+/**\r
+  Register ESAL Class and its associated global.\r
+  \r
+  This function Registers one or more Extended SAL services in a given\r
+  class along with the associated global context.\r
+  This function is only available prior to ExitBootServices().\r
+\r
+  @param  ClassGuidLo          GUID of function class, lower 64-bits\r
+  @param  ClassGuidHi          GUID of function class, upper 64-bits\r
+  @param  ModuleGlobal         Module global for Function.\r
+  @param  ...                  List of Function/FunctionId pairs, ended by NULL\r
+\r
+  @retval EFI_SUCCESS          The Extended SAL services were registered.\r
+  @retval EFI_UNSUPPORTED      This function was called after ExitBootServices().\r
+  @retval EFI_OUT_OF_RESOURCES There are not enough resources available to register one or more of the specified services.\r
+  @retval Other                ClassGuid could not be installed onto a new handle.  \r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RegisterEsalClass (\r
+  IN  CONST UINT64    ClassGuidLo,\r
+  IN  CONST UINT64    ClassGuidHi,\r
+  IN  VOID            *ModuleGlobal,  OPTIONAL\r
+  ...\r
+  );\r
+\r
+/**\r
+  Calls an Extended SAL Class service that was previously registered with RegisterEsalClass().\r
+  \r
+  This function calls an Extended SAL Class service that was previously registered with RegisterEsalClass().\r
+\r
+  @param  ClassGuidLo    GUID of function, lower 64-bits\r
+  @param  ClassGuidHi    GUID of function, upper 64-bits\r
+  @param  FunctionId     Function in ClassGuid to call\r
+  @param  Arg2           Argument 2 ClassGuid/FunctionId defined\r
+  @param  Arg3           Argument 3 ClassGuid/FunctionId defined\r
+  @param  Arg4           Argument 4 ClassGuid/FunctionId defined\r
+  @param  Arg5           Argument 5 ClassGuid/FunctionId defined\r
+  @param  Arg6           Argument 6 ClassGuid/FunctionId defined\r
+  @param  Arg7           Argument 7 ClassGuid/FunctionId defined\r
+  @param  Arg8           Argument 8 ClassGuid/FunctionId defined\r
+  \r
+  @retval EFI_SAL_ERROR  The address of ExtendedSalProc() can not be determined\r
+                         for the current CPU execution mode.\r
+  @retval Other          See the return status from ExtendedSalProc() in the\r
+                         EXTENDED_SAL_BOOT_SERVICE_PROTOCOL.  \r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalCall (\r
+  IN UINT64  ClassGuidLo,\r
+  IN UINT64  ClassGuidHi,\r
+  IN UINT64  FunctionId,\r
+  IN UINT64  Arg2,\r
+  IN UINT64  Arg3,\r
+  IN UINT64  Arg4,\r
+  IN UINT64  Arg5,\r
+  IN UINT64  Arg6,\r
+  IN UINT64  Arg7,\r
+  IN UINT64  Arg8\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalStallFunctionId service of Extended SAL Stall Services Class.\r
+  \r
+  This function is a wrapper for the EsalStallFunctionId service of Extended SAL\r
+  Stall Services Class. See EsalStallFunctionId of Extended SAL Specification.\r
+\r
+  @param  Microseconds                  The number of microseconds to delay.\r
+\r
+  @retval EFI_SAL_SUCCESS               Call completed without error.\r
+  @retval EFI_SAL_INVALID_ARGUMENT      Invalid argument.\r
+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR Virtual address not registered\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalStall (\r
+  IN UINTN  Microseconds\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalSetNewPalEntryFunctionId service of Extended SAL PAL Services Services Class.\r
+  \r
+  This function is a wrapper for the EsalSetNewPalEntryFunctionId service of Extended SAL\r
+  PAL Services Services Class. See EsalSetNewPalEntryFunctionId of Extended SAL Specification.\r
+\r
+  @param  PhysicalAddress                If TRUE, then PalEntryPoint is a physical address.\r
+                                         If FALSE, then PalEntryPoint is a virtual address.\r
+  @param  PalEntryPoint                  The PAL Entry Point being set.\r
+\r
+  @retval EFI_SAL_SUCCESS                The PAL Entry Point was set.\r
+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR  This function was called in virtual mode before\r
+                                         virtual mappings for the specified Extended SAL\r
+                                         Procedure are available.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalSetNewPalEntry (\r
+  IN BOOLEAN  PhysicalAddress,\r
+  IN UINT64   PalEntryPoint\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalGetNewPalEntryFunctionId service of Extended SAL PAL Services Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetNewPalEntryFunctionId service of Extended SAL\r
+  PAL Services Services Class. See EsalGetNewPalEntryFunctionId of Extended SAL Specification.\r
+\r
+  @param  PhysicalAddress                If TRUE, then PalEntryPoint is a physical address.\r
+                                         If FALSE, then PalEntryPoint is a virtual address.\r
+\r
+  @retval EFI_SAL_SUCCESS                The PAL Entry Point was retrieved and returned in\r
+                                         SAL_RETURN_REGS.r9.\r
+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR  This function was called in virtual mode before\r
+                                         virtual mappings for the specified Extended SAL\r
+                                         Procedure are available.\r
+  @return r9                             PAL entry point retrieved.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetNewPalEntry (\r
+  IN BOOLEAN  PhysicalAddress\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalGetStateBufferFunctionId service of Extended SAL MCA Log Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetStateBufferFunctionId service of Extended SAL\r
+  MCA Log Services Class. See EsalGetStateBufferFunctionId of Extended SAL Specification.\r
+\r
+  @param  McaType               See type parameter of SAL Procedure SAL_GET_STATE_INFO.\r
+  @param  McaBuffer             A pointer to the base address of the returned buffer.\r
+                                Copied from SAL_RETURN_REGS.r9.\r
+  @param  BufferSize            A pointer to the size, in bytes, of the returned buffer.\r
+                                Copied from SAL_RETURN_REGS.r10.\r
+\r
+  @retval EFI_SAL_SUCCESS       The memory buffer to store error records was returned in r9 and r10.\r
+  @retval EFI_OUT_OF_RESOURCES  A memory buffer for string error records in not available\r
+  @return r9                    Base address of the returned buffer\r
+  @return r10                   Size of the returned buffer in bytes\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetStateBuffer (\r
+  IN  UINT64  McaType,\r
+  OUT UINT8   **McaBuffer,\r
+  OUT UINTN   *BufferSize\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalSaveStateBufferFunctionId service of Extended SAL MCA Log Services Class.\r
+  \r
+  This function is a wrapper for the EsalSaveStateBufferFunctionId service of Extended SAL\r
+  MCA Log Services Class. See EsalSaveStateBufferFunctionId of Extended SAL Specification.\r
+\r
+  @param  McaType      See type parameter of SAL Procedure SAL_GET_STATE_INFO.\r
+\r
+  @retval EFI_SUCCESS  The memory buffer containing the error record was written to nonvolatile storage.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalSaveStateBuffer (\r
+  IN  UINT64  McaType\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalGetVectorsFunctionId service of Extended SAL Base Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetVectorsFunctionId service of Extended SAL\r
+  Base Services Class. See EsalGetVectorsFunctionId of Extended SAL Specification.\r
+\r
+  @param  VectorType               The vector type to retrieve.\r
+                                   0 - MCA, 1 - BSP INIT, 2 - BOOT_RENDEZ, 3 - AP INIT.\r
+\r
+  @retval EFI_SAL_SUCCESS          Call completed without error.\r
+  @retval EFI_SAL_INVALID_ARGUMENT Invalid argument.\r
+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered\r
+                                   with the SAL Procedure SAL_SET_VECTORS.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetVectors (\r
+  IN  UINT64  VectorType\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalMcGetParamsFunctionId service of Extended SAL Base Services Class.\r
+  \r
+  This function is a wrapper for the EsalMcGetParamsFunctionId service of Extended SAL\r
+  Base Services Class. See EsalMcGetParamsFunctionId of Extended SAL Specification.\r
+\r
+  @param  ParamInfoType            The parameter type to retrieve.\r
+                                   1 - rendezvous interrupt\r
+                                   2 - wake up\r
+                                   3 - Corrected Platform Error Vector.\r
+\r
+  @retval EFI_SAL_SUCCESS          Call completed without error.\r
+  @retval EFI_SAL_INVALID_ARGUMENT Invalid argument.\r
+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered\r
+                                   with the SAL Procedure SAL_MC_SET_PARAMS.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalMcGetParams (\r
+  IN  UINT64  ParamInfoType\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalMcGetParamsFunctionId service of Extended SAL Base Services Class.\r
+  \r
+  This function is a wrapper for the EsalMcGetParamsFunctionId service of Extended SAL\r
+  Base Services Class. See EsalMcGetParamsFunctionId of Extended SAL Specification.\r
+\r
+  @retval EFI_SAL_SUCCESS          Call completed without error.\r
+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered\r
+                                   with the SAL Procedure SAL_MC_SET_PARAMS.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalMcGetMcParams (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalGetMcCheckinFlagsFunctionId service of Extended SAL Base Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetMcCheckinFlagsFunctionId service of Extended SAL\r
+  Base Services Class. See EsalGetMcCheckinFlagsFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuIndex         The index of the CPU of set of enabled CPUs to check.\r
+\r
+  @retval EFI_SAL_SUCCESS  The checkin status of the requested CPU was returned.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetMcCheckinFlags (\r
+  IN  UINT64  CpuIndex\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalAddCpuDataFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalAddCpuDataFunctionId service of Extended SAL\r
+  MP Services Class. See EsalAddCpuDataFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId                 The Global ID for the CPU being added.\r
+  @param  Enabled                     The enable flag for the CPU being added.\r
+                                      TRUE means the CPU is enabled.\r
+                                      FALSE means the CPU is disabled.\r
+  @param  PalCompatibility            The PAL Compatibility value for the CPU being added.\r
+\r
+  @retval EFI_SAL_SUCCESS             The CPU was added to the database.\r
+  @retval EFI_SAL_NOT_ENOUGH_SCRATCH  There are not enough resource available to add the CPU.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalAddCpuData (\r
+  IN UINT64   CpuGlobalId,\r
+  IN BOOLEAN  Enabled,\r
+  IN UINT64   PalCompatibility\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalRemoveCpuDataFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalRemoveCpuDataFunctionId service of Extended SAL\r
+  MP Services Class. See EsalRemoveCpuDataFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId             The Global ID for the CPU being removed.\r
+\r
+  @retval EFI_SAL_SUCCESS         The CPU was removed from the database.\r
+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalRemoveCpuData (\r
+  IN UINT64  CpuGlobalId\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalModifyCpuDataFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalModifyCpuDataFunctionId service of Extended SAL\r
+  MP Services Class. See EsalModifyCpuDataFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId             The Global ID for the CPU being modified.\r
+  @param  Enabled                 The enable flag for the CPU being modified.\r
+                                  TRUE means the CPU is enabled.\r
+                                  FALSE means the CPU is disabled.\r
+  @param  PalCompatibility        The PAL Compatibility value for the CPU being modified.\r
+\r
+  @retval EFI_SAL_SUCCESS         The CPU database was updated.\r
+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalModifyCpuData (\r
+  IN UINT64   CpuGlobalId,\r
+  IN BOOLEAN  Enabled,\r
+  IN UINT64   PalCompatibility\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalGetCpuDataByIdFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetCpuDataByIdFunctionId service of Extended SAL\r
+  MP Services Class. See EsalGetCpuDataByIdFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId             The Global ID for the CPU being looked up.\r
+  @param  IndexByEnabledCpu       If TRUE, then the index of set of enabled CPUs of database is returned.\r
+                                  If FALSE, then the index of set of all CPUs of database is returned.\r
+\r
+  @retval EFI_SAL_SUCCESS         The information on the specified CPU was returned.\r
+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetCpuDataById (\r
+  IN UINT64   CpuGlobalId,\r
+  IN BOOLEAN  IndexByEnabledCpu\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalGetCpuDataByIndexFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetCpuDataByIndexFunctionId service of Extended SAL\r
+  MP Services Class. See EsalGetCpuDataByIndexFunctionId of Extended SAL Specification.\r
+\r
+  @param  Index                   The Global ID for the CPU being modified.\r
+  @param  IndexByEnabledCpu       If TRUE, then the index of set of enabled CPUs of database is returned.\r
+                                  If FALSE, then the index of set of all CPUs of database is returned.\r
+\r
+  @retval EFI_SAL_SUCCESS         The information on the specified CPU was returned.\r
+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetCpuDataByIndex (\r
+  IN UINT64   Index,\r
+  IN BOOLEAN  IndexByEnabledCpu\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalWhoAmIFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalWhoAmIFunctionId service of Extended SAL\r
+  MP Services Class. See EsalWhoAmIFunctionId of Extended SAL Specification.\r
+\r
+  @param  IndexByEnabledCpu       If TRUE, then the index of set of enabled CPUs of database is returned.\r
+                                  If FALSE, then the index of set of all CPUs of database is returned.\r
+\r
+  @retval EFI_SAL_SUCCESS         The Global ID for the calling CPU was returned.\r
+  @retval EFI_SAL_NO_INFORMATION  The calling CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalWhoAmI (\r
+  IN BOOLEAN  IndexByEnabledCpu\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalNumProcessors service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalNumProcessors service of Extended SAL\r
+  MP Services Class. See EsalNumProcessors of Extended SAL Specification.\r
+\r
+  @retval EFI_SAL_SUCCESS    The information on the number of CPUs in the platform\r
+                             was returned.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalNumProcessors (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalSetMinStateFnctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalSetMinStateFnctionId service of Extended SAL\r
+  MP Services Class. See EsalSetMinStateFnctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId              The Global ID for the CPU whose MINSTATE pointer is being set.\r
+  @param  MinStatePointer          The physical address of the MINSTATE buffer for the CPU\r
+                                   specified by CpuGlobalId.\r
+\r
+  @retval EFI_SAL_SUCCESS          The MINSTATE pointer was set for the specified CPU.\r
+  @retval EFI_SAL_NO_INFORMATION   The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalSetMinState (\r
+  IN UINT64                CpuGlobalId,\r
+  IN EFI_PHYSICAL_ADDRESS  MinStatePointer\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalGetMinStateFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetMinStateFunctionId service of Extended SAL\r
+  MP Services Class. See EsalGetMinStateFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId            The Global ID for the CPU whose MINSTATE pointer is being retrieved.\r
+\r
+  @retval EFI_SAL_SUCCESS        The MINSTATE pointer for the specified CPU was retrieved.\r
+  @retval EFI_SAL_NO_INFORMATION The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetMinState (\r
+  IN UINT64  CpuGlobalId\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalMcsGetStateInfoFunctionId service of Extended SAL MCA Services Class.\r
+  \r
+  This function is a wrapper for the EsalMcsGetStateInfoFunctionId service of Extended SAL\r
+  MCA Services Class. See EsalMcsGetStateInfoFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId               The Global ID for the CPU whose MCA state buffer is being retrieved.\r
+  @param  StateBufferPointer        A pointer to the returned MCA state buffer.\r
+  @param  RequiredStateBufferSize   A pointer to the size, in bytes, of the returned MCA state buffer.\r
+\r
+  @retval EFI_SUCCESS               MINSTATE successfully got and size calculated.\r
+  @retval EFI_SAL_NO_INFORMATION    Fail to get MINSTATE.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalMcaGetStateInfo (\r
+  IN  UINT64                CpuGlobalId,\r
+  OUT EFI_PHYSICAL_ADDRESS  *StateBufferPointer,\r
+  OUT UINT64                *RequiredStateBufferSize\r
+  );\r
+\r
+/**\r
+  Wrapper for the EsalMcaRegisterCpuFunctionId service of Extended SAL MCA Services Class.\r
+  \r
+  This function is a wrapper for the EsalMcaRegisterCpuFunctionId service of Extended SAL\r
+  MCA Services Class. See EsalMcaRegisterCpuFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId              The Global ID for the CPU whose MCA state buffer is being set.\r
+  @param  StateBufferPointer       A pointer to the MCA state buffer.\r
+\r
+  @retval EFI_SAL_NO_INFORMATION   Cannot get the processor info with the CpuId\r
+  @retval EFI_SUCCESS              Save the processor's state info successfully\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalMcaRegisterCpu (\r
+  IN UINT64                CpuGlobalId,\r
+  IN EFI_PHYSICAL_ADDRESS  StateBufferPointer\r
+  );\r
+\r
+#endif\r
diff --git a/MdePkg/Library/DxeExtendedSalLib/DxeExtendedSalLib.inf b/MdePkg/Library/DxeExtendedSalLib/DxeExtendedSalLib.inf
new file mode 100644 (file)
index 0000000..e5ec8c9
--- /dev/null
@@ -0,0 +1,44 @@
+## @file\r
+#  The library implements the Extended SAL Library Class for boot service only modules.\r
+#\r
+#  Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  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
+#  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
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DxeExtendedSalLib\r
+  FILE_GUID                      = 8FDED21D-7AB5-4c26-8CF7-20EC4DB9861D\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = ExtendedSalLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION \r
+  CONSTRUCTOR                    = DxeExtendedSalLibConstruct\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IPF\r
+#\r
+\r
+[Sources.IPF]\r
+  ExtendedSalLib.c\r
+  Ipf/AsmExtendedSalLib.s\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiBootServicesTableLib\r
+\r
+[Protocols]\r
+  gEfiExtendedSalBootServiceProtocolGuid        # PROTOCOL ALWAYS_CONSUMED\r
+\r
+[Depex]\r
+  gEfiExtendedSalBootServiceProtocolGuid\r
diff --git a/MdePkg/Library/DxeExtendedSalLib/ExtendedSalLib.c b/MdePkg/Library/DxeExtendedSalLib/ExtendedSalLib.c
new file mode 100644 (file)
index 0000000..82266f5
--- /dev/null
@@ -0,0 +1,999 @@
+/** @file\r
+  The library implements the Extended SAL Library Class for boot service only modules.\r
+\r
+  Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  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 <PiDxe.h>\r
+\r
+#include <Protocol/ExtendedSalBootService.h>\r
+#include <Protocol/ExtendedSalServiceClasses.h>\r
+\r
+#include <Library/ExtendedSalLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+/**\r
+  Stores the physical plabel of ESAL entrypoint.\r
+\r
+  This assembly function stores the physical plabel of ESAL entrypoint\r
+  where GetEsalEntryPoint() can easily retrieve.\r
+\r
+  @param  EntryPoint  Physical address of ESAL entrypoint\r
+  @param  Gp          Physical GP of ESAL entrypoint\r
+\r
+  @return r8 = EFI_SAL_SUCCESS\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+SetEsalPhysicalEntryPoint (\r
+  IN  UINT64  EntryPoint,\r
+  IN  UINT64  Gp\r
+  );\r
+\r
+/**\r
+  Retrieves plabel of ESAL entrypoint.\r
+\r
+  This function retrives plabel of ESAL entrypoint stored by\r
+  SetEsalPhysicalEntryPoint().\r
+\r
+  @return r8  = EFI_SAL_SUCCESS\r
+          r9  = Physical Plabel\r
+          r10 = Virtual Plabel\r
+          r11 = PSR\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+GetEsalEntryPoint (\r
+  VOID\r
+  );\r
+\r
+EXTENDED_SAL_BOOT_SERVICE_PROTOCOL  *mEsalBootService = NULL;\r
+EFI_PLABEL                          mPlabel;\r
+\r
+/**\r
+  Constructor function to get Extended SAL Boot Service Protocol, and initializes\r
+  physical plabel of ESAL entrypoint.\r
+  \r
+  This function first locates Extended SAL Boot Service Protocol and caches it in global variable.\r
+  Then it initializes the physical plable of ESAL entrypoint, and stores\r
+  it where GetEsalEntryPoint() can easily retrieve.\r
+\r
+  @param  ImageHandle   The firmware allocated handle for the EFI image.\r
+  @param  SystemTable   A pointer to the EFI System Table.\r
+\r
+  @retval  EFI_SUCCESS  Plable of ESAL entrypoint successfully stored.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeExtendedSalLibConstruct (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+  EFI_PLABEL  *Plabel;\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // The protocol contains a function pointer, which is an indirect procedure call.\r
+  // An indirect procedure call goes through a plabel, and pointer to a function is\r
+  // a pointer to a plabel. To implement indirect procedure calls that can work in\r
+  // both physical and virtual mode, two plabels are required (one physical and one\r
+  // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it\r
+  // away. We cache it in a module global, so we can register the vitrual version.\r
+  //\r
+  Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, (VOID **) &mEsalBootService);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Plabel              = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;\r
+  mPlabel.EntryPoint  = Plabel->EntryPoint;\r
+  mPlabel.GP          = Plabel->GP;\r
+  //\r
+  // Stores the physical plabel of ESAL entrypoint where GetEsalEntryPoint() can easily retrieve.\r
+  //\r
+  SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Registers function of ESAL class and it's associated global.\r
+  \r
+  This function registers function of ESAL class, together with its associated global.\r
+  It is worker function for RegisterEsalClass().\r
+  It is only for boot time.\r
+\r
+  @param  FunctionId     ID of function to register\r
+  @param  ClassGuidLo    GUID of ESAL class, lower 64-bits\r
+  @param  ClassGuidHi    GUID of ESAL class, upper 64-bits\r
+  @param  Function       Function to register with ClassGuid/FunctionId pair\r
+  @param  ModuleGlobal   Module global for the function.\r
+\r
+  @return Status returned by RegisterExtendedSalProc() of Extended SAL Boot Service Protocol\r
+\r
+**/\r
+EFI_STATUS\r
+RegisterEsalFunction (\r
+  IN  UINT64                                    FunctionId,\r
+  IN  UINT64                                    ClassGuidLo,\r
+  IN  UINT64                                    ClassGuidHi,\r
+  IN  SAL_INTERNAL_EXTENDED_SAL_PROC            Function,\r
+  IN  VOID                                      *ModuleGlobal\r
+  )\r
+{\r
+  return mEsalBootService->RegisterExtendedSalProc (\r
+                             mEsalBootService,\r
+                             ClassGuidLo,\r
+                             ClassGuidHi,\r
+                             FunctionId,\r
+                             Function,\r
+                             ModuleGlobal\r
+                             );\r
+}\r
+\r
+/**\r
+  Registers ESAL Class and it's associated global.\r
+  \r
+  This function registers one or more Extended SAL services in a given\r
+  class along with the associated global context.\r
+  This function is only available prior to ExitBootServices().\r
+\r
+  @param  ClassGuidLo          GUID of function class, lower 64-bits\r
+  @param  ClassGuidHi          GUID of function class, upper 64-bits\r
+  @param  ModuleGlobal         Module global for the class.\r
+  @param  ...                  List of Function/FunctionId pairs, ended by NULL\r
+  \r
+  @retval EFI_SUCCESS          The Extended SAL services were registered.\r
+  @retval EFI_UNSUPPORTED      This function was called after ExitBootServices().\r
+  @retval EFI_OUT_OF_RESOURCES There are not enough resources available to register one or more of the specified services.\r
+  @retval Other                ClassGuid could not be installed onto a new handle.  \r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RegisterEsalClass (\r
+  IN  CONST UINT64    ClassGuidLo,\r
+  IN  CONST UINT64    ClassGuidHi,\r
+  IN  VOID            *ModuleGlobal,  OPTIONAL\r
+  ...\r
+  )\r
+{\r
+  VA_LIST                         Args;\r
+  EFI_STATUS                      Status;\r
+  SAL_INTERNAL_EXTENDED_SAL_PROC  Function;\r
+  UINT64                          FunctionId;\r
+  EFI_HANDLE                      NewHandle;\r
+  EFI_GUID                        ClassGuid;\r
+\r
+  VA_START (Args, ModuleGlobal);\r
+\r
+  //\r
+  // Register all functions of the class to register.\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  while (!EFI_ERROR (Status)) {\r
+    Function = (SAL_INTERNAL_EXTENDED_SAL_PROC) VA_ARG (Args, SAL_INTERNAL_EXTENDED_SAL_PROC);\r
+    //\r
+    // NULL serves as the end mark of function list\r
+    //\r
+    if (Function == NULL) {\r
+      break;\r
+    }\r
+\r
+    FunctionId = VA_ARG (Args, UINT64);\r
+\r
+    Status = RegisterEsalFunction (FunctionId, ClassGuidLo, ClassGuidHi, Function, ModuleGlobal);\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  NewHandle = NULL;\r
+  *((UINT64 *)(&ClassGuid) + 0) = ClassGuidLo;\r
+  *((UINT64 *)(&ClassGuid) + 1) = ClassGuidHi;\r
+  return gBS->InstallProtocolInterface (\r
+                &NewHandle,\r
+                &ClassGuid,\r
+                EFI_NATIVE_INTERFACE,\r
+                NULL\r
+                );\r
+}\r
+\r
+/**\r
+  Calls an Extended SAL Class service that was previously registered with RegisterEsalClass().\r
+  \r
+  This function gets the entrypoint of Extended SAL, and calls an Extended SAL Class service\r
+  that was previously registered with RegisterEsalClass() through this entrypoint.\r
+\r
+  @param  ClassGuidLo     GUID of function, lower 64-bits\r
+  @param  ClassGuidHi     GUID of function, upper 64-bits\r
+  @param  FunctionId      Function in ClassGuid to call\r
+  @param  Arg2            Argument 2 ClassGuid/FunctionId defined\r
+  @param  Arg3            Argument 3 ClassGuid/FunctionId defined\r
+  @param  Arg4            Argument 4 ClassGuid/FunctionId defined\r
+  @param  Arg5            Argument 5 ClassGuid/FunctionId defined\r
+  @param  Arg6            Argument 6 ClassGuid/FunctionId defined\r
+  @param  Arg7            Argument 7 ClassGuid/FunctionId defined\r
+  @param  Arg8            Argument 8 ClassGuid/FunctionId defined\r
+  \r
+  @retval EFI_SAL_SUCCESS ESAL procedure successfully called.\r
+  @retval EFI_SAL_ERROR   The address of ExtendedSalProc() can not be correctly\r
+                          initialized.\r
+  @retval Other           Status returned from ExtendedSalProc() service of\r
+                          EXTENDED_SAL_BOOT_SERVICE_PROTOCOL.  \r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalCall (\r
+  IN UINT64  ClassGuidLo,\r
+  IN UINT64  ClassGuidHi,\r
+  IN UINT64  FunctionId,\r
+  IN UINT64  Arg2,\r
+  IN UINT64  Arg3,\r
+  IN UINT64  Arg4,\r
+  IN UINT64  Arg5,\r
+  IN UINT64  Arg6,\r
+  IN UINT64  Arg7,\r
+  IN UINT64  Arg8\r
+  )\r
+{\r
+  SAL_RETURN_REGS       ReturnReg;\r
+  EXTENDED_SAL_PROC     EsalProc;\r
+\r
+  //\r
+  // Get the entrypoint of Extended SAL\r
+  //\r
+  ReturnReg = GetEsalEntryPoint ();\r
+  if (*(UINT64 *)ReturnReg.r9 == 0 && *(UINT64 *)(ReturnReg.r9 + 8) == 0) {\r
+    //\r
+    // The ESAL Entry Point could not be initialized\r
+    //\r
+    ReturnReg.Status = EFI_SAL_ERROR;\r
+    return ReturnReg;\r
+  }\r
+\r
+  //\r
+  // Test PSR.it which is BIT36\r
+  //\r
+  if ((ReturnReg.r11 & BIT36) != 0) {\r
+    //\r
+    // Virtual mode plabel to entry point\r
+    //\r
+    EsalProc = (EXTENDED_SAL_PROC) ReturnReg.r10;\r
+  } else {\r
+    //\r
+    // Physical mode plabel to entry point\r
+    //\r
+    EsalProc = (EXTENDED_SAL_PROC) ReturnReg.r9;\r
+  }\r
+\r
+  return EsalProc (\r
+           ClassGuidLo,\r
+           ClassGuidHi,\r
+           FunctionId,\r
+           Arg2,\r
+           Arg3,\r
+           Arg4,\r
+           Arg5,\r
+           Arg6,\r
+           Arg7,\r
+           Arg8\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalStallFunctionId service of Extended SAL Stall Services Class.\r
+  \r
+  This function is a wrapper for the EsalStallFunctionId service of Extended SAL\r
+  Stall Services Class. See EsalStallFunctionId of Extended SAL Specification.\r
+\r
+  @param  Microseconds                  The number of microseconds to delay.\r
+\r
+  @retval EFI_SAL_SUCCESS               Call completed without error.\r
+  @retval EFI_SAL_INVALID_ARGUMENT      Invalid argument.\r
+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR Virtual address not registered\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalStall (\r
+  IN UINTN  Microseconds\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_LO, \r
+           EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_HI, \r
+           StallFunctionId, \r
+           Microseconds, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalSetNewPalEntryFunctionId service of Extended SAL PAL Services Services Class.\r
+  \r
+  This function is a wrapper for the EsalSetNewPalEntryFunctionId service of Extended SAL\r
+  PAL Services Services Class. See EsalSetNewPalEntryFunctionId of Extended SAL Specification.\r
+\r
+  @param  PhysicalAddress                If TRUE, then PalEntryPoint is a physical address.\r
+                                         If FALSE, then PalEntryPoint is a virtual address.\r
+  @param  PalEntryPoint                  The PAL Entry Point being set.\r
+\r
+  @retval EFI_SAL_SUCCESS                The PAL Entry Point was set.\r
+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR  This function was called in virtual mode before\r
+                                         virtual mappings for the specified Extended SAL\r
+                                         Procedure are available.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalSetNewPalEntry (\r
+  IN BOOLEAN  PhysicalAddress,\r
+  IN UINT64   PalEntryPoint\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO, \r
+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,\r
+           SetNewPalEntryFunctionId, \r
+           PhysicalAddress, \r
+           PalEntryPoint, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetNewPalEntryFunctionId service of Extended SAL PAL Services Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetNewPalEntryFunctionId service of Extended SAL\r
+  PAL Services Services Class. See EsalGetNewPalEntryFunctionId of Extended SAL Specification.\r
+\r
+  @param  PhysicalAddress                If TRUE, then PalEntryPoint is a physical address.\r
+                                         If FALSE, then PalEntryPoint is a virtual address.\r
+\r
+  @retval EFI_SAL_SUCCESS                The PAL Entry Point was retrieved and returned in\r
+                                         SAL_RETURN_REGS.r9.\r
+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR  This function was called in virtual mode before\r
+                                         virtual mappings for the specified Extended SAL\r
+                                         Procedure are available.\r
+  @return r9                             PAL entry point retrieved.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetNewPalEntry (\r
+  IN BOOLEAN  PhysicalAddress\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,\r
+           GetNewPalEntryFunctionId, \r
+           PhysicalAddress, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetStateBufferFunctionId service of Extended SAL MCA Log Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetStateBufferFunctionId service of Extended SAL\r
+  MCA Log Services Class. See EsalGetStateBufferFunctionId of Extended SAL Specification.\r
+\r
+  @param  McaType               See type parameter of SAL Procedure SAL_GET_STATE_INFO.\r
+  @param  McaBuffer             A pointer to the base address of the returned buffer.\r
+                                Copied from SAL_RETURN_REGS.r9.\r
+  @param  BufferSize            A pointer to the size, in bytes, of the returned buffer.\r
+                                Copied from SAL_RETURN_REGS.r10.\r
+\r
+  @retval EFI_SAL_SUCCESS       The memory buffer to store error records was returned in r9 and r10.\r
+  @retval EFI_OUT_OF_RESOURCES  A memory buffer for string error records in not available\r
+  @return r9                    Base address of the returned buffer\r
+  @return r10                   Size of the returned buffer in bytes\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetStateBuffer (\r
+  IN  UINT64  McaType,\r
+  OUT UINT8   **McaBuffer,\r
+  OUT UINTN   *BufferSize\r
+  )\r
+{\r
+  SAL_RETURN_REGS Regs;\r
+\r
+  Regs = EsalCall (\r
+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalGetStateBufferFunctionId, \r
+           McaType, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+\r
+  *McaBuffer  = (UINT8 *) Regs.r9;\r
+  *BufferSize = Regs.r10;\r
+\r
+  return Regs;\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalSaveStateBufferFunctionId service of Extended SAL MCA Log Services Class.\r
+  \r
+  This function is a wrapper for the EsalSaveStateBufferFunctionId service of Extended SAL\r
+  MCA Log Services Class. See EsalSaveStateBufferFunctionId of Extended SAL Specification.\r
+\r
+  @param  McaType      See type parameter of SAL Procedure SAL_GET_STATE_INFO.\r
+\r
+  @retval EFI_SUCCESS  The memory buffer containing the error record was written to nonvolatile storage.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalSaveStateBuffer (\r
+  IN  UINT64  McaType\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalSaveStateBufferFunctionId, \r
+           McaType, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetVectorsFunctionId service of Extended SAL Base Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetVectorsFunctionId service of Extended SAL\r
+  Base Services Class. See EsalGetVectorsFunctionId of Extended SAL Specification.\r
+\r
+  @param  VectorType               The vector type to retrieve.\r
+                                   0 - MCA, 1 - BSP INIT, 2 - BOOT_RENDEZ, 3 - AP INIT.\r
+\r
+  @retval EFI_SAL_SUCCESS          Call completed without error.\r
+  @retval EFI_SAL_INVALID_ARGUMENT Invalid argument.\r
+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered\r
+                                   with the SAL Procedure SAL_SET_VECTORS.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetVectors (\r
+  IN  UINT64  VectorType\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalGetVectorsFunctionId, \r
+           VectorType, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalMcGetParamsFunctionId service of Extended SAL Base Services Class.\r
+  \r
+  This function is a wrapper for the EsalMcGetParamsFunctionId service of Extended SAL\r
+  Base Services Class. See EsalMcGetParamsFunctionId of Extended SAL Specification.\r
+\r
+  @param  ParamInfoType            The parameter type to retrieve.\r
+                                   1 - rendezvous interrupt\r
+                                   2 - wake up\r
+                                   3 - Corrected Platform Error Vector.\r
+\r
+  @retval EFI_SAL_SUCCESS          Call completed without error.\r
+  @retval EFI_SAL_INVALID_ARGUMENT Invalid argument.\r
+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered\r
+                                   with the SAL Procedure SAL_MC_SET_PARAMS.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalMcGetParams (\r
+  IN  UINT64  ParamInfoType\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalMcGetParamsFunctionId, \r
+           ParamInfoType, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalMcGetParamsFunctionId service of Extended SAL Base Services Class.\r
+  \r
+  This function is a wrapper for the EsalMcGetParamsFunctionId service of Extended SAL\r
+  Base Services Class. See EsalMcGetParamsFunctionId of Extended SAL Specification.\r
+\r
+  @retval EFI_SAL_SUCCESS          Call completed without error.\r
+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered\r
+                                   with the SAL Procedure SAL_MC_SET_PARAMS.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalMcGetMcParams (\r
+  VOID\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalMcGetMcParamsFunctionId, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetMcCheckinFlagsFunctionId service of Extended SAL Base Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetMcCheckinFlagsFunctionId service of Extended SAL\r
+  Base Services Class. See EsalGetMcCheckinFlagsFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuIndex         The index of the CPU of set of enabled CPUs to check.\r
+\r
+  @retval EFI_SAL_SUCCESS  The checkin status of the requested CPU was returned.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetMcCheckinFlags (\r
+  IN  UINT64  CpuIndex\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalGetMcCheckinFlagsFunctionId, \r
+           CpuIndex, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalAddCpuDataFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalAddCpuDataFunctionId service of Extended SAL\r
+  MP Services Class. See EsalAddCpuDataFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId                 The Global ID for the CPU being added.\r
+  @param  Enabled                     The enable flag for the CPU being added.\r
+                                      TRUE means the CPU is enabled.\r
+                                      FALSE means the CPU is disabled.\r
+  @param  PalCompatibility            The PAL Compatibility value for the CPU being added.\r
+\r
+  @retval EFI_SAL_SUCCESS             The CPU was added to the database.\r
+  @retval EFI_SAL_NOT_ENOUGH_SCRATCH  There are not enough resource available to add the CPU.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalAddCpuData (\r
+  IN UINT64   CpuGlobalId,\r
+  IN BOOLEAN  Enabled,\r
+  IN UINT64   PalCompatibility\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           AddCpuDataFunctionId, \r
+           CpuGlobalId, \r
+           Enabled, \r
+           PalCompatibility, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalRemoveCpuDataFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalRemoveCpuDataFunctionId service of Extended SAL\r
+  MP Services Class. See EsalRemoveCpuDataFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId             The Global ID for the CPU being removed.\r
+\r
+  @retval EFI_SAL_SUCCESS         The CPU was removed from the database.\r
+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalRemoveCpuData (\r
+  IN UINT64  CpuGlobalId\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           RemoveCpuDataFunctionId, \r
+           CpuGlobalId, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalModifyCpuDataFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalModifyCpuDataFunctionId service of Extended SAL\r
+  MP Services Class. See EsalModifyCpuDataFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId             The Global ID for the CPU being modified.\r
+  @param  Enabled                 The enable flag for the CPU being modified.\r
+                                  TRUE means the CPU is enabled.\r
+                                  FALSE means the CPU is disabled.\r
+  @param  PalCompatibility        The PAL Compatibility value for the CPU being modified.\r
+\r
+  @retval EFI_SAL_SUCCESS         The CPU database was updated.\r
+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalModifyCpuData (\r
+  IN UINT64   CpuGlobalId,\r
+  IN BOOLEAN  Enabled,\r
+  IN UINT64   PalCompatibility\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           ModifyCpuDataFunctionId, \r
+           CpuGlobalId, \r
+           Enabled, \r
+           PalCompatibility, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetCpuDataByIdFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetCpuDataByIdFunctionId service of Extended SAL\r
+  MP Services Class. See EsalGetCpuDataByIdFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId             The Global ID for the CPU being looked up.\r
+  @param  IndexByEnabledCpu       If TRUE, then the index of set of enabled CPUs of database is returned.\r
+                                  If FALSE, then the index of set of all CPUs of database is returned.\r
+\r
+  @retval EFI_SAL_SUCCESS         The information on the specified CPU was returned.\r
+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetCpuDataById (\r
+  IN UINT64   CpuGlobalId,\r
+  IN BOOLEAN  IndexByEnabledCpu\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           GetCpuDataByIDFunctionId, \r
+           CpuGlobalId, \r
+           IndexByEnabledCpu, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetCpuDataByIndexFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetCpuDataByIndexFunctionId service of Extended SAL\r
+  MP Services Class. See EsalGetCpuDataByIndexFunctionId of Extended SAL Specification.\r
+\r
+  @param  Index                   The Global ID for the CPU being modified.\r
+  @param  IndexByEnabledCpu       If TRUE, then the index of set of enabled CPUs of database is returned.\r
+                                  If FALSE, then the index of set of all CPUs of database is returned.\r
+\r
+  @retval EFI_SAL_SUCCESS         The information on the specified CPU was returned.\r
+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetCpuDataByIndex (\r
+  IN UINT64   Index,\r
+  IN BOOLEAN  IndexByEnabledCpu\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           GetCpuDataByIndexFunctionId, \r
+           Index, \r
+           IndexByEnabledCpu, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalWhoAmIFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalWhoAmIFunctionId service of Extended SAL\r
+  MP Services Class. See EsalWhoAmIFunctionId of Extended SAL Specification.\r
+\r
+  @param  IndexByEnabledCpu       If TRUE, then the index of set of enabled CPUs of database is returned.\r
+                                  If FALSE, then the index of set of all CPUs of database is returned.\r
+\r
+  @retval EFI_SAL_SUCCESS         The Global ID for the calling CPU was returned.\r
+  @retval EFI_SAL_NO_INFORMATION  The calling CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalWhoAmI (\r
+  IN BOOLEAN  IndexByEnabledCpu\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           CurrentProcInfoFunctionId, \r
+           IndexByEnabledCpu, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalNumProcessors service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalNumProcessors service of Extended SAL\r
+  MP Services Class. See EsalNumProcessors of Extended SAL Specification.\r
+\r
+  @retval EFI_SAL_SUCCESS    The information on the number of CPUs in the platform\r
+                             was returned.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalNumProcessors (\r
+  VOID\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           NumProcessorsFunctionId, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalSetMinStateFnctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalSetMinStateFnctionId service of Extended SAL\r
+  MP Services Class. See EsalSetMinStateFnctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId              The Global ID for the CPU whose MINSTATE pointer is being set.\r
+  @param  MinStatePointer          The physical address of the MINSTATE buffer for the CPU\r
+                                   specified by CpuGlobalId.\r
+\r
+  @retval EFI_SAL_SUCCESS          The MINSTATE pointer was set for the specified CPU.\r
+  @retval EFI_SAL_NO_INFORMATION   The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalSetMinState (\r
+  IN UINT64                CpuGlobalId,\r
+  IN EFI_PHYSICAL_ADDRESS  MinStatePointer\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           SetMinStateFunctionId, \r
+           CpuGlobalId, \r
+           MinStatePointer, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetMinStateFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetMinStateFunctionId service of Extended SAL\r
+  MP Services Class. See EsalGetMinStateFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId            The Global ID for the CPU whose MINSTATE pointer is being retrieved.\r
+\r
+  @retval EFI_SAL_SUCCESS        The MINSTATE pointer for the specified CPU was retrieved.\r
+  @retval EFI_SAL_NO_INFORMATION The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetMinState (\r
+  IN UINT64  CpuGlobalId\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           GetMinStateFunctionId, \r
+           CpuGlobalId, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalMcsGetStateInfoFunctionId service of Extended SAL MCA Services Class.\r
+  \r
+  This function is a wrapper for the EsalMcsGetStateInfoFunctionId service of Extended SAL\r
+  MCA Services Class. See EsalMcsGetStateInfoFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId               The Global ID for the CPU whose MCA state buffer is being retrieved.\r
+  @param  StateBufferPointer        A pointer to the returned MCA state buffer.\r
+  @param  RequiredStateBufferSize   A pointer to the size, in bytes, of the returned MCA state buffer.\r
+\r
+  @retval EFI_SUCCESS               MINSTATE successfully got and size calculated.\r
+  @retval EFI_SAL_NO_INFORMATION    Fail to get MINSTATE.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalMcaGetStateInfo (\r
+  IN  UINT64                CpuGlobalId,\r
+  OUT EFI_PHYSICAL_ADDRESS  *StateBufferPointer,\r
+  OUT UINT64                *RequiredStateBufferSize\r
+  )\r
+{\r
+  SAL_RETURN_REGS  Regs;\r
+\r
+  Regs = EsalCall (\r
+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_HI,\r
+           McaGetStateInfoFunctionId, \r
+           CpuGlobalId, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+\r
+  *StateBufferPointer      = (EFI_PHYSICAL_ADDRESS) Regs.r9;\r
+  *RequiredStateBufferSize = (UINT64) Regs.r10;\r
+\r
+  return Regs;\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalMcaRegisterCpuFunctionId service of Extended SAL MCA Services Class.\r
+  \r
+  This function is a wrapper for the EsalMcaRegisterCpuFunctionId service of Extended SAL\r
+  MCA Services Class. See EsalMcaRegisterCpuFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId              The Global ID for the CPU whose MCA state buffer is being set.\r
+  @param  StateBufferPointer       A pointer to the MCA state buffer.\r
+\r
+  @retval EFI_SAL_NO_INFORMATION   Cannot get the processor info with the CpuId\r
+  @retval EFI_SUCCESS              Save the processor's state info successfully\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalMcaRegisterCpu (\r
+  IN UINT64                CpuGlobalId,\r
+  IN EFI_PHYSICAL_ADDRESS  StateBufferPointer\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_HI,\r
+           McaRegisterCpuFunctionId, \r
+           CpuGlobalId, \r
+           StateBufferPointer, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
diff --git a/MdePkg/Library/DxeExtendedSalLib/Ipf/AsmExtendedSalLib.s b/MdePkg/Library/DxeExtendedSalLib/Ipf/AsmExtendedSalLib.s
new file mode 100644 (file)
index 0000000..f1c4366
--- /dev/null
@@ -0,0 +1,97 @@
+/// @file\r
+///  Assembly procedures to get and set ESAL entry point.\r
+///\r
+/// Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+/// 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
+.auto\r
+.text\r
+\r
+#include  "IpfMacro.i"\r
+\r
+//\r
+// Exports\r
+//\r
+ASM_GLOBAL GetEsalEntryPoint\r
+\r
+//-----------------------------------------------------------------------------\r
+//++\r
+// GetEsalEntryPoint\r
+//\r
+// Return Esal global and PSR register.\r
+//\r
+// On Entry :\r
+//\r
+//\r
+// Return Value:\r
+//        r8  = EFI_SAL_SUCCESS\r
+//        r9  = Physical Plabel\r
+//        r10 = Virtual Plabel\r
+//        r11 = psr\r
+// \r
+// As per static calling conventions. \r
+// \r
+//--\r
+//---------------------------------------------------------------------------\r
+PROCEDURE_ENTRY (GetEsalEntryPoint)\r
+\r
+      NESTED_SETUP (0,8,0,0)\r
+\r
+EsalCalcStart:\r
+      mov   r8  = ip;;\r
+      add   r8  = (EsalEntryPoint - EsalCalcStart), r8;;\r
+      mov   r9  = r8;;\r
+      add   r10 = 0x10, r8;;\r
+      mov   r11 = psr;;\r
+      mov   r8  = r0;;\r
+\r
+      NESTED_RETURN\r
+\r
+PROCEDURE_EXIT (GetEsalEntryPoint)\r
+\r
+//-----------------------------------------------------------------------------\r
+//++\r
+// SetEsalPhysicalEntryPoint\r
+//\r
+// Set the dispatcher entry point\r
+//\r
+// On Entry:\r
+//  in0 = Physical address of Esal Dispatcher\r
+//  in1 = Physical GP\r
+//\r
+// Return Value: \r
+//   r8 = EFI_SAL_SUCCESS\r
+// \r
+// As per static calling conventions. \r
+// \r
+//--\r
+//---------------------------------------------------------------------------\r
+PROCEDURE_ENTRY (SetEsalPhysicalEntryPoint)\r
+\r
+      NESTED_SETUP (2,8,0,0)\r
+\r
+EsalCalcStart1:\r
+      mov   r8   = ip;;\r
+      add   r8   = (EsalEntryPoint - EsalCalcStart1), r8;;\r
+      st8   [r8] = in0;;\r
+      add   r8   = 0x08, r8;;\r
+      st8   [r8] = in1;;\r
+      mov   r8   = r0;;\r
+\r
+      NESTED_RETURN\r
+\r
+PROCEDURE_EXIT (SetEsalPhysicalEntryPoint)\r
+\r
+.align 32\r
+EsalEntryPoint: \r
+    data8 0   // Physical Entry\r
+    data8 0   //         GP\r
+    data8 0   // Virtual Entry\r
+    data8 0   //         GP\r
diff --git a/MdePkg/Library/DxeIoLibEsal/DxeIoLibEsal.inf b/MdePkg/Library/DxeIoLibEsal/DxeIoLibEsal.inf
new file mode 100644 (file)
index 0000000..c0d9a33
--- /dev/null
@@ -0,0 +1,48 @@
+## @file\r
+# Component description file for a CPU I/O Library that layers on top of \r
+# Itanium ESAL services.\r
+#\r
+# I/O Library implementation that uses Itanium ESAL services for I/O\r
+#  and MMIO operations.\r
+#\r
+# Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials are licensed and made available\r
+# under the terms and conditions of the BSD License which accompanies this \r
+# 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
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DxeIoLibEsal\r
+  FILE_GUID                      = 0D8E6E4E-B029-475f-9122-60A3FEDBA8C0\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = IoLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IPF\r
+#\r
+\r
+[Sources]\r
+  IoHighLevel.c\r
+  IoLib.c\r
+  IoLibMmioBuffer.c\r
+  DxeIoLibEsalInternal.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+  ExtendedSalLib\r
+  BaseLib\r
+  DebugLib\r
+\r
+[Depex]\r
+  gEfiExtendedSalBaseIoServicesProtocolGuid\r
diff --git a/MdePkg/Library/DxeIoLibEsal/DxeIoLibEsalInternal.h b/MdePkg/Library/DxeIoLibEsal/DxeIoLibEsalInternal.h
new file mode 100644 (file)
index 0000000..c6dd4af
--- /dev/null
@@ -0,0 +1,28 @@
+/** @file\r
+  Internal include file for the I/O Library using ESAL services.\r
+  \r
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials are licensed and made available\r
+  under the terms and conditions of the BSD License which accompanies this\r
+  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
+#ifndef __DXE_IO_LIB_ESAL_INTERNAL_H_\r
+#define __DXE_IO_LIB_ESAL_INTERNAL_H_\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/CpuIo2.h>\r
+#include <Protocol/ExtendedSalServiceClasses.h>\r
+\r
+#include <Library/IoLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/ExtendedSalLib.h>\r
+\r
+#endif\r
diff --git a/MdePkg/Library/DxeIoLibEsal/IoHighLevel.c b/MdePkg/Library/DxeIoLibEsal/IoHighLevel.c
new file mode 100644 (file)
index 0000000..c84a8b7
--- /dev/null
@@ -0,0 +1,2263 @@
+/** @file\r
+  High-level Io/Mmio functions.\r
+\r
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  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 "DxeIoLibEsalInternal.h"\r
+\r
+/**\r
+  Reads an 8-bit I/O port, performs a bitwise OR, and writes the\r
+  result back to the 8-bit I/O port.\r
+\r
+  Reads the 8-bit I/O port specified by Port, performs a bitwise OR\r
+  between the read result and the value specified by OrData, and writes the\r
+  result to the 8-bit I/O port specified by Port. The value written to the I/O\r
+  port is returned. This function must guarantee that all I/O read and write\r
+  operations are serialized.\r
+\r
+  If 8-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port    The I/O port to write.\r
+  @param  OrData  The value to OR with the value read from the I/O port.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+IoOr8 (\r
+  IN      UINTN                     Port,\r
+  IN      UINT8                     OrData\r
+  )\r
+{\r
+  return IoWrite8 (Port, (UINT8)(IoRead8 (Port) | OrData));\r
+}\r
+\r
+/**\r
+  Reads an 8-bit I/O port, performs a bitwise AND, and writes the result back\r
+  to the 8-bit I/O port.\r
+\r
+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between\r
+  the read result and the value specified by AndData, and writes the result to\r
+  the 8-bit I/O port specified by Port. The value written to the I/O port is\r
+  returned. This function must guarantee that all I/O read and write operations\r
+  are serialized.\r
+\r
+  If 8-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port    The I/O port to write.\r
+  @param  AndData The value to AND with the value read from the I/O port.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+IoAnd8 (\r
+  IN      UINTN                     Port,\r
+  IN      UINT8                     AndData\r
+  )\r
+{\r
+  return IoWrite8 (Port, (UINT8)(IoRead8 (Port) & AndData));\r
+}\r
+\r
+/**\r
+  Reads an 8-bit I/O port, performs a bitwise AND followed by a bitwise\r
+  inclusive OR, and writes the result back to the 8-bit I/O port.\r
+\r
+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between\r
+  the read result and the value specified by AndData, performs a bitwise OR\r
+  between the result of the AND operation and the value specified by OrData,\r
+  and writes the result to the 8-bit I/O port specified by Port. The value\r
+  written to the I/O port is returned. This function must guarantee that all\r
+  I/O read and write operations are serialized.\r
+\r
+  If 8-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port    The I/O port to write.\r
+  @param  AndData The value to AND with the value read from the I/O port.\r
+  @param  OrData  The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+IoAndThenOr8 (\r
+  IN      UINTN                     Port,\r
+  IN      UINT8                     AndData,\r
+  IN      UINT8                     OrData\r
+  )\r
+{\r
+  return IoWrite8 (Port, (UINT8)((IoRead8 (Port) & AndData) | OrData));\r
+}\r
+\r
+/**\r
+  Reads a bit field of an I/O register.\r
+\r
+  Reads the bit field in an 8-bit I/O register. The bit field is specified by\r
+  the StartBit and the EndBit. The value of the bit field is returned.\r
+\r
+  If 8-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to read.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+IoBitFieldRead8 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit\r
+  )\r
+{\r
+  return BitFieldRead8 (IoRead8 (Port), StartBit, EndBit);\r
+}\r
+\r
+/**\r
+  Writes a bit field to an I/O register.\r
+\r
+  Writes Value to the bit field of the I/O register. The bit field is specified\r
+  by the StartBit and the EndBit. All other bits in the destination I/O\r
+  register are preserved. The value written to the I/O port is returned. Extra\r
+  left bits in Value are stripped.\r
+\r
+  If 8-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  Value     New value of the bit field.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+IoBitFieldWrite8 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT8                     Value\r
+  )\r
+{\r
+  return IoWrite8 (\r
+           Port,\r
+           BitFieldWrite8 (IoRead8 (Port), StartBit, EndBit, Value)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in an 8-bit port, performs a bitwise OR, and writes the\r
+  result back to the bit field in the 8-bit port.\r
+\r
+  Reads the 8-bit I/O port specified by Port, performs a bitwise OR\r
+  between the read result and the value specified by OrData, and writes the\r
+  result to the 8-bit I/O port specified by Port. The value written to the I/O\r
+  port is returned. This function must guarantee that all I/O read and write\r
+  operations are serialized. Extra left bits in OrData are stripped.\r
+\r
+  If 8-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  OrData    The value to OR with the value read from the I/O port.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+IoBitFieldOr8 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT8                     OrData\r
+  )\r
+{\r
+  return IoWrite8 (\r
+           Port,\r
+           BitFieldOr8 (IoRead8 (Port), StartBit, EndBit, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in an 8-bit port, performs a bitwise AND, and writes the\r
+  result back to the bit field in the 8-bit port.\r
+\r
+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between\r
+  the read result and the value specified by AndData, and writes the result to\r
+  the 8-bit I/O port specified by Port. The value written to the I/O port is\r
+  returned. This function must guarantee that all I/O read and write operations\r
+  are serialized. Extra left bits in AndData are stripped.\r
+\r
+  If 8-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  AndData   The value to AND with the value read from the I/O port.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+IoBitFieldAnd8 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT8                     AndData\r
+  )\r
+{\r
+  return IoWrite8 (\r
+           Port,\r
+           BitFieldAnd8 (IoRead8 (Port), StartBit, EndBit, AndData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a\r
+  bitwise OR, and writes the result back to the bit field in the\r
+  8-bit port.\r
+\r
+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND followed\r
+  by a bitwise OR between the read result and the value specified by\r
+  AndData, and writes the result to the 8-bit I/O port specified by Port. The\r
+  value written to the I/O port is returned. This function must guarantee that\r
+  all I/O read and write operations are serialized. Extra left bits in both\r
+  AndData and OrData are stripped.\r
+\r
+  If 8-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  AndData   The value to AND with the value read from the I/O port.\r
+  @param  OrData    The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+IoBitFieldAndThenOr8 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT8                     AndData,\r
+  IN      UINT8                     OrData\r
+  )\r
+{\r
+  return IoWrite8 (\r
+           Port,\r
+           BitFieldAndThenOr8 (IoRead8 (Port), StartBit, EndBit, AndData, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a 16-bit I/O port, performs a bitwise OR, and writes the\r
+  result back to the 16-bit I/O port.\r
+\r
+  Reads the 16-bit I/O port specified by Port, performs a bitwise OR\r
+  between the read result and the value specified by OrData, and writes the\r
+  result to the 16-bit I/O port specified by Port. The value written to the I/O\r
+  port is returned. This function must guarantee that all I/O read and write\r
+  operations are serialized.\r
+\r
+  If 16-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port    The I/O port to write.\r
+  @param  OrData  The value to OR with the value read from the I/O port.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+IoOr16 (\r
+  IN      UINTN                     Port,\r
+  IN      UINT16                    OrData\r
+  )\r
+{\r
+  return IoWrite16 (Port, (UINT16)(IoRead16 (Port) | OrData));\r
+}\r
+\r
+/**\r
+  Reads a 16-bit I/O port, performs a bitwise AND, and writes the result back\r
+  to the 16-bit I/O port.\r
+\r
+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between\r
+  the read result and the value specified by AndData, and writes the result to\r
+  the 16-bit I/O port specified by Port. The value written to the I/O port is\r
+  returned. This function must guarantee that all I/O read and write operations\r
+  are serialized.\r
+\r
+  If 16-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port    The I/O port to write.\r
+  @param  AndData The value to AND with the value read from the I/O port.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+IoAnd16 (\r
+  IN      UINTN                     Port,\r
+  IN      UINT16                    AndData\r
+  )\r
+{\r
+  return IoWrite16 (Port, (UINT16)(IoRead16 (Port) & AndData));\r
+}\r
+\r
+/**\r
+  Reads a 16-bit I/O port, performs a bitwise AND followed by a bitwise\r
+  inclusive OR, and writes the result back to the 16-bit I/O port.\r
+\r
+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between\r
+  the read result and the value specified by AndData, performs a bitwise OR\r
+  between the result of the AND operation and the value specified by OrData,\r
+  and writes the result to the 16-bit I/O port specified by Port. The value\r
+  written to the I/O port is returned. This function must guarantee that all\r
+  I/O read and write operations are serialized.\r
+\r
+  If 16-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port    The I/O port to write.\r
+  @param  AndData The value to AND with the value read from the I/O port.\r
+  @param  OrData  The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+IoAndThenOr16 (\r
+  IN      UINTN                     Port,\r
+  IN      UINT16                    AndData,\r
+  IN      UINT16                    OrData\r
+  )\r
+{\r
+  return IoWrite16 (Port, (UINT16)((IoRead16 (Port) & AndData) | OrData));\r
+}\r
+\r
+/**\r
+  Reads a bit field of an I/O register.\r
+\r
+  Reads the bit field in a 16-bit I/O register. The bit field is specified by\r
+  the StartBit and the EndBit. The value of the bit field is returned.\r
+\r
+  If 16-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to read.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+IoBitFieldRead16 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit\r
+  )\r
+{\r
+  return BitFieldRead16 (IoRead16 (Port), StartBit, EndBit);\r
+}\r
+\r
+/**\r
+  Writes a bit field to an I/O register.\r
+\r
+  Writes Value to the bit field of the I/O register. The bit field is specified\r
+  by the StartBit and the EndBit. All other bits in the destination I/O\r
+  register are preserved. The value written to the I/O port is returned. Extra\r
+  left bits in Value are stripped.\r
+\r
+  If 16-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  Value     New value of the bit field.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+IoBitFieldWrite16 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT16                    Value\r
+  )\r
+{\r
+  return IoWrite16 (\r
+           Port,\r
+           BitFieldWrite16 (IoRead16 (Port), StartBit, EndBit, Value)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 16-bit port, performs a bitwise OR, and writes the\r
+  result back to the bit field in the 16-bit port.\r
+\r
+  Reads the 16-bit I/O port specified by Port, performs a bitwise OR\r
+  between the read result and the value specified by OrData, and writes the\r
+  result to the 16-bit I/O port specified by Port. The value written to the I/O\r
+  port is returned. This function must guarantee that all I/O read and write\r
+  operations are serialized. Extra left bits in OrData are stripped.\r
+\r
+  If 16-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  OrData    The value to OR with the value read from the I/O port.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+IoBitFieldOr16 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT16                    OrData\r
+  )\r
+{\r
+  return IoWrite16 (\r
+           Port,\r
+           BitFieldOr16 (IoRead16 (Port), StartBit, EndBit, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 16-bit port, performs a bitwise AND, and writes the\r
+  result back to the bit field in the 16-bit port.\r
+\r
+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between\r
+  the read result and the value specified by AndData, and writes the result to\r
+  the 16-bit I/O port specified by Port. The value written to the I/O port is\r
+  returned. This function must guarantee that all I/O read and write operations\r
+  are serialized. Extra left bits in AndData are stripped.\r
+\r
+  If 16-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  AndData   The value to AND with the value read from the I/O port.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+IoBitFieldAnd16 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT16                    AndData\r
+  )\r
+{\r
+  return IoWrite16 (\r
+           Port,\r
+           BitFieldAnd16 (IoRead16 (Port), StartBit, EndBit, AndData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a\r
+  bitwise OR, and writes the result back to the bit field in the\r
+  16-bit port.\r
+\r
+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND followed\r
+  by a bitwise OR between the read result and the value specified by\r
+  AndData, and writes the result to the 16-bit I/O port specified by Port. The\r
+  value written to the I/O port is returned. This function must guarantee that\r
+  all I/O read and write operations are serialized. Extra left bits in both\r
+  AndData and OrData are stripped.\r
+\r
+  If 16-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  AndData   The value to AND with the value read from the I/O port.\r
+  @param  OrData    The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+IoBitFieldAndThenOr16 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT16                    AndData,\r
+  IN      UINT16                    OrData\r
+  )\r
+{\r
+  return IoWrite16 (\r
+           Port,\r
+           BitFieldAndThenOr16 (IoRead16 (Port), StartBit, EndBit, AndData, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a 32-bit I/O port, performs a bitwise OR, and writes the\r
+  result back to the 32-bit I/O port.\r
+\r
+  Reads the 32-bit I/O port specified by Port, performs a bitwise OR\r
+  between the read result and the value specified by OrData, and writes the\r
+  result to the 32-bit I/O port specified by Port. The value written to the I/O\r
+  port is returned. This function must guarantee that all I/O read and write\r
+  operations are serialized.\r
+\r
+  If 32-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port    The I/O port to write.\r
+  @param  OrData  The value to OR with the value read from the I/O port.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+IoOr32 (\r
+  IN      UINTN                     Port,\r
+  IN      UINT32                    OrData\r
+  )\r
+{\r
+  return IoWrite32 (Port, IoRead32 (Port) | OrData);\r
+}\r
+\r
+/**\r
+  Reads a 32-bit I/O port, performs a bitwise AND, and writes the result back\r
+  to the 32-bit I/O port.\r
+\r
+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between\r
+  the read result and the value specified by AndData, and writes the result to\r
+  the 32-bit I/O port specified by Port. The value written to the I/O port is\r
+  returned. This function must guarantee that all I/O read and write operations\r
+  are serialized.\r
+\r
+  If 32-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port    The I/O port to write.\r
+  @param  AndData The value to AND with the value read from the I/O port.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+IoAnd32 (\r
+  IN      UINTN                     Port,\r
+  IN      UINT32                    AndData\r
+  )\r
+{\r
+  return IoWrite32 (Port, IoRead32 (Port) & AndData);\r
+}\r
+\r
+/**\r
+  Reads a 32-bit I/O port, performs a bitwise AND followed by a bitwise\r
+  inclusive OR, and writes the result back to the 32-bit I/O port.\r
+\r
+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between\r
+  the read result and the value specified by AndData, performs a bitwise OR\r
+  between the result of the AND operation and the value specified by OrData,\r
+  and writes the result to the 32-bit I/O port specified by Port. The value\r
+  written to the I/O port is returned. This function must guarantee that all\r
+  I/O read and write operations are serialized.\r
+\r
+  If 32-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port    The I/O port to write.\r
+  @param  AndData The value to AND with the value read from the I/O port.\r
+  @param  OrData  The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+IoAndThenOr32 (\r
+  IN      UINTN                     Port,\r
+  IN      UINT32                    AndData,\r
+  IN      UINT32                    OrData\r
+  )\r
+{\r
+  return IoWrite32 (Port, (IoRead32 (Port) & AndData) | OrData);\r
+}\r
+\r
+/**\r
+  Reads a bit field of an I/O register.\r
+\r
+  Reads the bit field in a 32-bit I/O register. The bit field is specified by\r
+  the StartBit and the EndBit. The value of the bit field is returned.\r
+\r
+  If 32-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to read.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+IoBitFieldRead32 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit\r
+  )\r
+{\r
+  return BitFieldRead32 (IoRead32 (Port), StartBit, EndBit);\r
+}\r
+\r
+/**\r
+  Writes a bit field to an I/O register.\r
+\r
+  Writes Value to the bit field of the I/O register. The bit field is specified\r
+  by the StartBit and the EndBit. All other bits in the destination I/O\r
+  register are preserved. The value written to the I/O port is returned. Extra\r
+  left bits in Value are stripped.\r
+\r
+  If 32-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  Value     New value of the bit field.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+IoBitFieldWrite32 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT32                    Value\r
+  )\r
+{\r
+  return IoWrite32 (\r
+           Port,\r
+           BitFieldWrite32 (IoRead32 (Port), StartBit, EndBit, Value)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 32-bit port, performs a bitwise OR, and writes the\r
+  result back to the bit field in the 32-bit port.\r
+\r
+  Reads the 32-bit I/O port specified by Port, performs a bitwise OR\r
+  between the read result and the value specified by OrData, and writes the\r
+  result to the 32-bit I/O port specified by Port. The value written to the I/O\r
+  port is returned. This function must guarantee that all I/O read and write\r
+  operations are serialized. Extra left bits in OrData are stripped.\r
+\r
+  If 32-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  OrData    The value to OR with the value read from the I/O port.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+IoBitFieldOr32 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT32                    OrData\r
+  )\r
+{\r
+  return IoWrite32 (\r
+           Port,\r
+           BitFieldOr32 (IoRead32 (Port), StartBit, EndBit, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 32-bit port, performs a bitwise AND, and writes the\r
+  result back to the bit field in the 32-bit port.\r
+\r
+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between\r
+  the read result and the value specified by AndData, and writes the result to\r
+  the 32-bit I/O port specified by Port. The value written to the I/O port is\r
+  returned. This function must guarantee that all I/O read and write operations\r
+  are serialized. Extra left bits in AndData are stripped.\r
+\r
+  If 32-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  AndData   The value to AND with the value read from the I/O port.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+IoBitFieldAnd32 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT32                    AndData\r
+  )\r
+{\r
+  return IoWrite32 (\r
+           Port,\r
+           BitFieldAnd32 (IoRead32 (Port), StartBit, EndBit, AndData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a\r
+  bitwise OR, and writes the result back to the bit field in the\r
+  32-bit port.\r
+\r
+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND followed\r
+  by a bitwise OR between the read result and the value specified by\r
+  AndData, and writes the result to the 32-bit I/O port specified by Port. The\r
+  value written to the I/O port is returned. This function must guarantee that\r
+  all I/O read and write operations are serialized. Extra left bits in both\r
+  AndData and OrData are stripped.\r
+\r
+  If 32-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  AndData   The value to AND with the value read from the I/O port.\r
+  @param  OrData    The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+IoBitFieldAndThenOr32 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT32                    AndData,\r
+  IN      UINT32                    OrData\r
+  )\r
+{\r
+  return IoWrite32 (\r
+           Port,\r
+           BitFieldAndThenOr32 (IoRead32 (Port), StartBit, EndBit, AndData, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a 64-bit I/O port, performs a bitwise OR, and writes the\r
+  result back to the 64-bit I/O port.\r
+\r
+  Reads the 64-bit I/O port specified by Port, performs a bitwise OR\r
+  between the read result and the value specified by OrData, and writes the\r
+  result to the 64-bit I/O port specified by Port. The value written to the I/O\r
+  port is returned. This function must guarantee that all I/O read and write\r
+  operations are serialized.\r
+\r
+  If 64-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port    The I/O port to write.\r
+  @param  OrData  The value to OR with the value read from the I/O port.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+IoOr64 (\r
+  IN      UINTN                     Port,\r
+  IN      UINT64                    OrData\r
+  )\r
+{\r
+  return IoWrite64 (Port, IoRead64 (Port) | OrData);\r
+}\r
+\r
+/**\r
+  Reads a 64-bit I/O port, performs a bitwise AND, and writes the result back\r
+  to the 64-bit I/O port.\r
+\r
+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between\r
+  the read result and the value specified by AndData, and writes the result to\r
+  the 64-bit I/O port specified by Port. The value written to the I/O port is\r
+  returned. This function must guarantee that all I/O read and write operations\r
+  are serialized.\r
+\r
+  If 64-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port    The I/O port to write.\r
+  @param  AndData The value to AND with the value read from the I/O port.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+IoAnd64 (\r
+  IN      UINTN                     Port,\r
+  IN      UINT64                    AndData\r
+  )\r
+{\r
+  return IoWrite64 (Port, IoRead64 (Port) & AndData);\r
+}\r
+\r
+/**\r
+  Reads a 64-bit I/O port, performs a bitwise AND followed by a bitwise\r
+  inclusive OR, and writes the result back to the 64-bit I/O port.\r
+\r
+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between\r
+  the read result and the value specified by AndData, performs a bitwise OR\r
+  between the result of the AND operation and the value specified by OrData,\r
+  and writes the result to the 64-bit I/O port specified by Port. The value\r
+  written to the I/O port is returned. This function must guarantee that all\r
+  I/O read and write operations are serialized.\r
+\r
+  If 64-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port    The I/O port to write.\r
+  @param  AndData The value to AND with the value read from the I/O port.\r
+  @param  OrData  The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+IoAndThenOr64 (\r
+  IN      UINTN                     Port,\r
+  IN      UINT64                    AndData,\r
+  IN      UINT64                    OrData\r
+  )\r
+{\r
+  return IoWrite64 (Port, (IoRead64 (Port) & AndData) | OrData);\r
+}\r
+\r
+/**\r
+  Reads a bit field of an I/O register.\r
+\r
+  Reads the bit field in a 64-bit I/O register. The bit field is specified by\r
+  the StartBit and the EndBit. The value of the bit field is returned.\r
+\r
+  If 64-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 63, then ASSERT().\r
+  If EndBit is greater than 63, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to read.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..63.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+IoBitFieldRead64 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit\r
+  )\r
+{\r
+  return BitFieldRead64 (IoRead64 (Port), StartBit, EndBit);\r
+}\r
+\r
+/**\r
+  Writes a bit field to an I/O register.\r
+\r
+  Writes Value to the bit field of the I/O register. The bit field is specified\r
+  by the StartBit and the EndBit. All other bits in the destination I/O\r
+  register are preserved. The value written to the I/O port is returned. Extra\r
+  left bits in Value are stripped.\r
+\r
+  If 64-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 63, then ASSERT().\r
+  If EndBit is greater than 63, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  Value     New value of the bit field.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+IoBitFieldWrite64 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT64                    Value\r
+  )\r
+{\r
+  return IoWrite64 (\r
+           Port,\r
+           BitFieldWrite64 (IoRead64 (Port), StartBit, EndBit, Value)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 64-bit port, performs a bitwise OR, and writes the\r
+  result back to the bit field in the 64-bit port.\r
+\r
+  Reads the 64-bit I/O port specified by Port, performs a bitwise OR\r
+  between the read result and the value specified by OrData, and writes the\r
+  result to the 64-bit I/O port specified by Port. The value written to the I/O\r
+  port is returned. This function must guarantee that all I/O read and write\r
+  operations are serialized. Extra left bits in OrData are stripped.\r
+\r
+  If 64-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 63, then ASSERT().\r
+  If EndBit is greater than 63, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  OrData    The value to OR with the value read from the I/O port.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+IoBitFieldOr64 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT64                    OrData\r
+  )\r
+{\r
+  return IoWrite64 (\r
+           Port,\r
+           BitFieldOr64 (IoRead64 (Port), StartBit, EndBit, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 64-bit port, performs a bitwise AND, and writes the\r
+  result back to the bit field in the 64-bit port.\r
+\r
+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between\r
+  the read result and the value specified by AndData, and writes the result to\r
+  the 64-bit I/O port specified by Port. The value written to the I/O port is\r
+  returned. This function must guarantee that all I/O read and write operations\r
+  are serialized. Extra left bits in AndData are stripped.\r
+\r
+  If 64-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 63, then ASSERT().\r
+  If EndBit is greater than 63, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  AndData   The value to AND with the value read from the I/O port.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+IoBitFieldAnd64 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT64                    AndData\r
+  )\r
+{\r
+  return IoWrite64 (\r
+           Port,\r
+           BitFieldAnd64 (IoRead64 (Port), StartBit, EndBit, AndData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 64-bit port, performs a bitwise AND followed by a\r
+  bitwise OR, and writes the result back to the bit field in the\r
+  64-bit port.\r
+\r
+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND followed\r
+  by a bitwise OR between the read result and the value specified by\r
+  AndData, and writes the result to the 64-bit I/O port specified by Port. The\r
+  value written to the I/O port is returned. This function must guarantee that\r
+  all I/O read and write operations are serialized. Extra left bits in both\r
+  AndData and OrData are stripped.\r
+\r
+  If 64-bit I/O port operations are not supported, then ASSERT().\r
+  If StartBit is greater than 63, then ASSERT().\r
+  If EndBit is greater than 63, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Port      The I/O port to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  AndData   The value to AND with the value read from the I/O port.\r
+  @param  OrData    The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the I/O port.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+IoBitFieldAndThenOr64 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT64                    AndData,\r
+  IN      UINT64                    OrData\r
+  )\r
+{\r
+  return IoWrite64 (\r
+           Port,\r
+           BitFieldAndThenOr64 (IoRead64 (Port), StartBit, EndBit, AndData, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads an 8-bit MMIO register, performs a bitwise OR, and writes the\r
+  result back to the 8-bit MMIO register.\r
+\r
+  Reads the 8-bit MMIO register specified by Address, performs a bitwise\r
+  inclusive OR between the read result and the value specified by OrData, and\r
+  writes the result to the 8-bit MMIO register specified by Address. The value\r
+  written to the MMIO register is returned. This function must guarantee that\r
+  all MMIO read and write operations are serialized.\r
+\r
+  If 8-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+  @param  Address The MMIO register to write.\r
+  @param  OrData  The value to OR with the value read from the MMIO register.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+MmioOr8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT8                     OrData\r
+  )\r
+{\r
+  return MmioWrite8 (Address, (UINT8)(MmioRead8 (Address) | OrData));\r
+}\r
+\r
+/**\r
+  Reads an 8-bit MMIO register, performs a bitwise AND, and writes the result\r
+  back to the 8-bit MMIO register.\r
+\r
+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND\r
+  between the read result and the value specified by AndData, and writes the\r
+  result to the 8-bit MMIO register specified by Address. The value written to\r
+  the MMIO register is returned. This function must guarantee that all MMIO\r
+  read and write operations are serialized.\r
+\r
+  If 8-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+  @param  Address The MMIO register to write.\r
+  @param  AndData The value to AND with the value read from the MMIO register.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+MmioAnd8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT8                     AndData\r
+  )\r
+{\r
+  return MmioWrite8 (Address, (UINT8)(MmioRead8 (Address) & AndData));\r
+}\r
+\r
+/**\r
+  Reads an 8-bit MMIO register, performs a bitwise AND followed by a bitwise\r
+  inclusive OR, and writes the result back to the 8-bit MMIO register.\r
+\r
+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND\r
+  between the read result and the value specified by AndData, performs a\r
+  bitwise OR between the result of the AND operation and the value specified by\r
+  OrData, and writes the result to the 8-bit MMIO register specified by\r
+  Address. The value written to the MMIO register is returned. This function\r
+  must guarantee that all MMIO read and write operations are serialized.\r
+\r
+  If 8-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+\r
+  @param  Address The MMIO register to write.\r
+  @param  AndData The value to AND with the value read from the MMIO register.\r
+  @param  OrData  The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+MmioAndThenOr8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT8                     AndData,\r
+  IN      UINT8                     OrData\r
+  )\r
+{\r
+  return MmioWrite8 (Address, (UINT8)((MmioRead8 (Address) & AndData) | OrData));\r
+}\r
+\r
+/**\r
+  Reads a bit field of a MMIO register.\r
+\r
+  Reads the bit field in an 8-bit MMIO register. The bit field is specified by\r
+  the StartBit and the EndBit. The value of the bit field is returned.\r
+\r
+  If 8-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to read.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+MmioBitFieldRead8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit\r
+  )\r
+{\r
+  return BitFieldRead8 (MmioRead8 (Address), StartBit, EndBit);\r
+}\r
+\r
+/**\r
+  Writes a bit field to a MMIO register.\r
+\r
+  Writes Value to the bit field of the MMIO register. The bit field is\r
+  specified by the StartBit and the EndBit. All other bits in the destination\r
+  MMIO register are preserved. The new value of the 8-bit register is returned.\r
+\r
+  If 8-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  Value     New value of the bit field.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+MmioBitFieldWrite8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT8                     Value\r
+  )\r
+{\r
+  return MmioWrite8 (\r
+           Address,\r
+           BitFieldWrite8 (MmioRead8 (Address), StartBit, EndBit, Value)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in an 8-bit MMIO register, performs a bitwise OR, and\r
+  writes the result back to the bit field in the 8-bit MMIO register.\r
+\r
+  Reads the 8-bit MMIO register specified by Address, performs a bitwise\r
+  inclusive OR between the read result and the value specified by OrData, and\r
+  writes the result to the 8-bit MMIO register specified by Address. The value\r
+  written to the MMIO register is returned. This function must guarantee that\r
+  all MMIO read and write operations are serialized. Extra left bits in OrData\r
+  are stripped.\r
+\r
+  If 8-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  OrData    The value to OR with value read from the MMIO register.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+MmioBitFieldOr8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT8                     OrData\r
+  )\r
+{\r
+  return MmioWrite8 (\r
+           Address,\r
+           BitFieldOr8 (MmioRead8 (Address), StartBit, EndBit, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND, and\r
+  writes the result back to the bit field in the 8-bit MMIO register.\r
+\r
+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND\r
+  between the read result and the value specified by AndData, and writes the\r
+  result to the 8-bit MMIO register specified by Address. The value written to\r
+  the MMIO register is returned. This function must guarantee that all MMIO\r
+  read and write operations are serialized. Extra left bits in AndData are\r
+  stripped.\r
+\r
+  If 8-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  AndData   The value to AND with value read from the MMIO register.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+MmioBitFieldAnd8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT8                     AndData\r
+  )\r
+{\r
+  return MmioWrite8 (\r
+           Address,\r
+           BitFieldAnd8 (MmioRead8 (Address), StartBit, EndBit, AndData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND followed\r
+  by a bitwise OR, and writes the result back to the bit field in the\r
+  8-bit MMIO register.\r
+\r
+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND\r
+  followed by a bitwise OR between the read result and the value\r
+  specified by AndData, and writes the result to the 8-bit MMIO register\r
+  specified by Address. The value written to the MMIO register is returned.\r
+  This function must guarantee that all MMIO read and write operations are\r
+  serialized. Extra left bits in both AndData and OrData are stripped.\r
+\r
+  If 8-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  AndData   The value to AND with value read from the MMIO register.\r
+  @param  OrData    The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+MmioBitFieldAndThenOr8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT8                     AndData,\r
+  IN      UINT8                     OrData\r
+  )\r
+{\r
+  return MmioWrite8 (\r
+           Address,\r
+           BitFieldAndThenOr8 (MmioRead8 (Address), StartBit, EndBit, AndData, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a 16-bit MMIO register, performs a bitwise OR, and writes the\r
+  result back to the 16-bit MMIO register.\r
+\r
+  Reads the 16-bit MMIO register specified by Address, performs a bitwise\r
+  inclusive OR between the read result and the value specified by OrData, and\r
+  writes the result to the 16-bit MMIO register specified by Address. The value\r
+  written to the MMIO register is returned. This function must guarantee that\r
+  all MMIO read and write operations are serialized.\r
+\r
+  If 16-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+  @param  Address The MMIO register to write.\r
+  @param  OrData  The value to OR with the value read from the MMIO register.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+MmioOr16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT16                    OrData\r
+  )\r
+{\r
+  return MmioWrite16 (Address, (UINT16)(MmioRead16 (Address) | OrData));\r
+}\r
+\r
+/**\r
+  Reads a 16-bit MMIO register, performs a bitwise AND, and writes the result\r
+  back to the 16-bit MMIO register.\r
+\r
+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND\r
+  between the read result and the value specified by AndData, and writes the\r
+  result to the 16-bit MMIO register specified by Address. The value written to\r
+  the MMIO register is returned. This function must guarantee that all MMIO\r
+  read and write operations are serialized.\r
+\r
+  If 16-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+  @param  Address The MMIO register to write.\r
+  @param  AndData The value to AND with the value read from the MMIO register.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+MmioAnd16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT16                    AndData\r
+  )\r
+{\r
+  return MmioWrite16 (Address, (UINT16)(MmioRead16 (Address) & AndData));\r
+}\r
+\r
+/**\r
+  Reads a 16-bit MMIO register, performs a bitwise AND followed by a bitwise\r
+  inclusive OR, and writes the result back to the 16-bit MMIO register.\r
+\r
+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND\r
+  between the read result and the value specified by AndData, performs a\r
+  bitwise OR between the result of the AND operation and the value specified by\r
+  OrData, and writes the result to the 16-bit MMIO register specified by\r
+  Address. The value written to the MMIO register is returned. This function\r
+  must guarantee that all MMIO read and write operations are serialized.\r
+\r
+  If 16-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+\r
+  @param  Address The MMIO register to write.\r
+  @param  AndData The value to AND with the value read from the MMIO register.\r
+  @param  OrData  The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+MmioAndThenOr16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT16                    AndData,\r
+  IN      UINT16                    OrData\r
+  )\r
+{\r
+  return MmioWrite16 (Address, (UINT16)((MmioRead16 (Address) & AndData) | OrData));\r
+}\r
+\r
+/**\r
+  Reads a bit field of a MMIO register.\r
+\r
+  Reads the bit field in a 16-bit MMIO register. The bit field is specified by\r
+  the StartBit and the EndBit. The value of the bit field is returned.\r
+\r
+  If 16-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to read.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+MmioBitFieldRead16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit\r
+  )\r
+{\r
+  return BitFieldRead16 (MmioRead16 (Address), StartBit, EndBit);\r
+}\r
+\r
+/**\r
+  Writes a bit field to a MMIO register.\r
+\r
+  Writes Value to the bit field of the MMIO register. The bit field is\r
+  specified by the StartBit and the EndBit. All other bits in the destination\r
+  MMIO register are preserved. The new value of the 16-bit register is returned.\r
+\r
+  If 16-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  Value     New value of the bit field.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+MmioBitFieldWrite16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT16                    Value\r
+  )\r
+{\r
+  return MmioWrite16 (\r
+           Address,\r
+           BitFieldWrite16 (MmioRead16 (Address), StartBit, EndBit, Value)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 16-bit MMIO register, performs a bitwise OR, and\r
+  writes the result back to the bit field in the 16-bit MMIO register.\r
+\r
+  Reads the 16-bit MMIO register specified by Address, performs a bitwise\r
+  inclusive OR between the read result and the value specified by OrData, and\r
+  writes the result to the 16-bit MMIO register specified by Address. The value\r
+  written to the MMIO register is returned. This function must guarantee that\r
+  all MMIO read and write operations are serialized. Extra left bits in OrData\r
+  are stripped.\r
+\r
+  If 16-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  OrData    The value to OR with value read from the MMIO register.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+MmioBitFieldOr16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT16                    OrData\r
+  )\r
+{\r
+  return MmioWrite16 (\r
+           Address,\r
+           BitFieldOr16 (MmioRead16 (Address), StartBit, EndBit, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND, and\r
+  writes the result back to the bit field in the 16-bit MMIO register.\r
+\r
+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND\r
+  between the read result and the value specified by AndData, and writes the\r
+  result to the 16-bit MMIO register specified by Address. The value written to\r
+  the MMIO register is returned. This function must guarantee that all MMIO\r
+  read and write operations are serialized. Extra left bits in AndData are\r
+  stripped.\r
+\r
+  If 16-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  AndData   The value to AND with value read from the MMIO register.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+MmioBitFieldAnd16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT16                    AndData\r
+  )\r
+{\r
+  return MmioWrite16 (\r
+           Address,\r
+           BitFieldAnd16 (MmioRead16 (Address), StartBit, EndBit, AndData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND followed\r
+  by a bitwise OR, and writes the result back to the bit field in the\r
+  16-bit MMIO register.\r
+\r
+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND\r
+  followed by a bitwise OR between the read result and the value\r
+  specified by AndData, and writes the result to the 16-bit MMIO register\r
+  specified by Address. The value written to the MMIO register is returned.\r
+  This function must guarantee that all MMIO read and write operations are\r
+  serialized. Extra left bits in both AndData and OrData are stripped.\r
+\r
+  If 16-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  AndData   The value to AND with value read from the MMIO register.\r
+  @param  OrData    The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+MmioBitFieldAndThenOr16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT16                    AndData,\r
+  IN      UINT16                    OrData\r
+  )\r
+{\r
+  return MmioWrite16 (\r
+           Address,\r
+           BitFieldAndThenOr16 (MmioRead16 (Address), StartBit, EndBit, AndData, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a 32-bit MMIO register, performs a bitwise OR, and writes the\r
+  result back to the 32-bit MMIO register.\r
+\r
+  Reads the 32-bit MMIO register specified by Address, performs a bitwise\r
+  inclusive OR between the read result and the value specified by OrData, and\r
+  writes the result to the 32-bit MMIO register specified by Address. The value\r
+  written to the MMIO register is returned. This function must guarantee that\r
+  all MMIO read and write operations are serialized.\r
+\r
+  If 32-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+  @param  Address The MMIO register to write.\r
+  @param  OrData  The value to OR with the value read from the MMIO register.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+MmioOr32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT32                    OrData\r
+  )\r
+{\r
+  return MmioWrite32 (Address, MmioRead32 (Address) | OrData);\r
+}\r
+\r
+/**\r
+  Reads a 32-bit MMIO register, performs a bitwise AND, and writes the result\r
+  back to the 32-bit MMIO register.\r
+\r
+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND\r
+  between the read result and the value specified by AndData, and writes the\r
+  result to the 32-bit MMIO register specified by Address. The value written to\r
+  the MMIO register is returned. This function must guarantee that all MMIO\r
+  read and write operations are serialized.\r
+\r
+  If 32-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+  @param  Address The MMIO register to write.\r
+  @param  AndData The value to AND with the value read from the MMIO register.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+MmioAnd32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT32                    AndData\r
+  )\r
+{\r
+  return MmioWrite32 (Address, MmioRead32 (Address) & AndData);\r
+}\r
+\r
+/**\r
+  Reads a 32-bit MMIO register, performs a bitwise AND followed by a bitwise\r
+  inclusive OR, and writes the result back to the 32-bit MMIO register.\r
+\r
+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND\r
+  between the read result and the value specified by AndData, performs a\r
+  bitwise OR between the result of the AND operation and the value specified by\r
+  OrData, and writes the result to the 32-bit MMIO register specified by\r
+  Address. The value written to the MMIO register is returned. This function\r
+  must guarantee that all MMIO read and write operations are serialized.\r
+\r
+  If 32-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+\r
+  @param  Address The MMIO register to write.\r
+  @param  AndData The value to AND with the value read from the MMIO register.\r
+  @param  OrData  The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+MmioAndThenOr32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT32                    AndData,\r
+  IN      UINT32                    OrData\r
+  )\r
+{\r
+  return MmioWrite32 (Address, (MmioRead32 (Address) & AndData) | OrData);\r
+}\r
+\r
+/**\r
+  Reads a bit field of a MMIO register.\r
+\r
+  Reads the bit field in a 32-bit MMIO register. The bit field is specified by\r
+  the StartBit and the EndBit. The value of the bit field is returned.\r
+\r
+  If 32-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to read.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+MmioBitFieldRead32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit\r
+  )\r
+{\r
+  return BitFieldRead32 (MmioRead32 (Address), StartBit, EndBit);\r
+}\r
+\r
+/**\r
+  Writes a bit field to a MMIO register.\r
+\r
+  Writes Value to the bit field of the MMIO register. The bit field is\r
+  specified by the StartBit and the EndBit. All other bits in the destination\r
+  MMIO register are preserved. The new value of the 32-bit register is returned.\r
+\r
+  If 32-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  Value     New value of the bit field.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+MmioBitFieldWrite32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT32                    Value\r
+  )\r
+{\r
+  return MmioWrite32 (\r
+           Address,\r
+           BitFieldWrite32 (MmioRead32 (Address), StartBit, EndBit, Value)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 32-bit MMIO register, performs a bitwise OR, and\r
+  writes the result back to the bit field in the 32-bit MMIO register.\r
+\r
+  Reads the 32-bit MMIO register specified by Address, performs a bitwise\r
+  inclusive OR between the read result and the value specified by OrData, and\r
+  writes the result to the 32-bit MMIO register specified by Address. The value\r
+  written to the MMIO register is returned. This function must guarantee that\r
+  all MMIO read and write operations are serialized. Extra left bits in OrData\r
+  are stripped.\r
+\r
+  If 32-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  OrData    The value to OR with value read from the MMIO register.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+MmioBitFieldOr32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT32                    OrData\r
+  )\r
+{\r
+  return MmioWrite32 (\r
+           Address,\r
+           BitFieldOr32 (MmioRead32 (Address), StartBit, EndBit, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND, and\r
+  writes the result back to the bit field in the 32-bit MMIO register.\r
+\r
+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND\r
+  between the read result and the value specified by AndData, and writes the\r
+  result to the 32-bit MMIO register specified by Address. The value written to\r
+  the MMIO register is returned. This function must guarantee that all MMIO\r
+  read and write operations are serialized. Extra left bits in AndData are\r
+  stripped.\r
+\r
+  If 32-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  AndData   The value to AND with value read from the MMIO register.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+MmioBitFieldAnd32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT32                    AndData\r
+  )\r
+{\r
+  return MmioWrite32 (\r
+           Address,\r
+           BitFieldAnd32 (MmioRead32 (Address), StartBit, EndBit, AndData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND followed\r
+  by a bitwise OR, and writes the result back to the bit field in the\r
+  32-bit MMIO register.\r
+\r
+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND\r
+  followed by a bitwise OR between the read result and the value\r
+  specified by AndData, and writes the result to the 32-bit MMIO register\r
+  specified by Address. The value written to the MMIO register is returned.\r
+  This function must guarantee that all MMIO read and write operations are\r
+  serialized. Extra left bits in both AndData and OrData are stripped.\r
+\r
+  If 32-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  AndData   The value to AND with value read from the MMIO register.\r
+  @param  OrData    The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+MmioBitFieldAndThenOr32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT32                    AndData,\r
+  IN      UINT32                    OrData\r
+  )\r
+{\r
+  return MmioWrite32 (\r
+           Address,\r
+           BitFieldAndThenOr32 (MmioRead32 (Address), StartBit, EndBit, AndData, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a 64-bit MMIO register, performs a bitwise OR, and writes the\r
+  result back to the 64-bit MMIO register.\r
+\r
+  Reads the 64-bit MMIO register specified by Address, performs a bitwise\r
+  inclusive OR between the read result and the value specified by OrData, and\r
+  writes the result to the 64-bit MMIO register specified by Address. The value\r
+  written to the MMIO register is returned. This function must guarantee that\r
+  all MMIO read and write operations are serialized.\r
+\r
+  If 64-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+  @param  Address The MMIO register to write.\r
+  @param  OrData  The value to OR with the value read from the MMIO register.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+MmioOr64 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT64                    OrData\r
+  )\r
+{\r
+  return MmioWrite64 (Address, MmioRead64 (Address) | OrData);\r
+}\r
+\r
+/**\r
+  Reads a 64-bit MMIO register, performs a bitwise AND, and writes the result\r
+  back to the 64-bit MMIO register.\r
+\r
+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND\r
+  between the read result and the value specified by AndData, and writes the\r
+  result to the 64-bit MMIO register specified by Address. The value written to\r
+  the MMIO register is returned. This function must guarantee that all MMIO\r
+  read and write operations are serialized.\r
+\r
+  If 64-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+  @param  Address The MMIO register to write.\r
+  @param  AndData The value to AND with the value read from the MMIO register.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+MmioAnd64 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT64                    AndData\r
+  )\r
+{\r
+  return MmioWrite64 (Address, MmioRead64 (Address) & AndData);\r
+}\r
+\r
+/**\r
+  Reads a 64-bit MMIO register, performs a bitwise AND followed by a bitwise\r
+  inclusive OR, and writes the result back to the 64-bit MMIO register.\r
+\r
+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND\r
+  between the read result and the value specified by AndData, performs a\r
+  bitwise OR between the result of the AND operation and the value specified by\r
+  OrData, and writes the result to the 64-bit MMIO register specified by\r
+  Address. The value written to the MMIO register is returned. This function\r
+  must guarantee that all MMIO read and write operations are serialized.\r
+\r
+  If 64-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+\r
+  @param  Address The MMIO register to write.\r
+  @param  AndData The value to AND with the value read from the MMIO register.\r
+  @param  OrData  The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+MmioAndThenOr64 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT64                    AndData,\r
+  IN      UINT64                    OrData\r
+  )\r
+{\r
+  return MmioWrite64 (Address, (MmioRead64 (Address) & AndData) | OrData);\r
+}\r
+\r
+/**\r
+  Reads a bit field of a MMIO register.\r
+\r
+  Reads the bit field in a 64-bit MMIO register. The bit field is specified by\r
+  the StartBit and the EndBit. The value of the bit field is returned.\r
+\r
+  If 64-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 63, then ASSERT().\r
+  If EndBit is greater than 63, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to read.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..63.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+MmioBitFieldRead64 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit\r
+  )\r
+{\r
+  return BitFieldRead64 (MmioRead64 (Address), StartBit, EndBit);\r
+}\r
+\r
+/**\r
+  Writes a bit field to a MMIO register.\r
+\r
+  Writes Value to the bit field of the MMIO register. The bit field is\r
+  specified by the StartBit and the EndBit. All other bits in the destination\r
+  MMIO register are preserved. The new value of the 64-bit register is returned.\r
+\r
+  If 64-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 63, then ASSERT().\r
+  If EndBit is greater than 63, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  Value     New value of the bit field.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+MmioBitFieldWrite64 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT64                    Value\r
+  )\r
+{\r
+  return MmioWrite64 (\r
+           Address,\r
+           BitFieldWrite64 (MmioRead64 (Address), StartBit, EndBit, Value)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 64-bit MMIO register, performs a bitwise OR, and\r
+  writes the result back to the bit field in the 64-bit MMIO register.\r
+\r
+  Reads the 64-bit MMIO register specified by Address, performs a bitwise\r
+  inclusive OR between the read result and the value specified by OrData, and\r
+  writes the result to the 64-bit MMIO register specified by Address. The value\r
+  written to the MMIO register is returned. This function must guarantee that\r
+  all MMIO read and write operations are serialized. Extra left bits in OrData\r
+  are stripped.\r
+\r
+  If 64-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 63, then ASSERT().\r
+  If EndBit is greater than 63, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  OrData    The value to OR with value read from the MMIO register.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+MmioBitFieldOr64 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT64                    OrData\r
+  )\r
+{\r
+  return MmioWrite64 (\r
+           Address,\r
+           BitFieldOr64 (MmioRead64 (Address), StartBit, EndBit, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND, and\r
+  writes the result back to the bit field in the 64-bit MMIO register.\r
+\r
+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND\r
+  between the read result and the value specified by AndData, and writes the\r
+  result to the 64-bit MMIO register specified by Address. The value written to\r
+  the MMIO register is returned. This function must guarantee that all MMIO\r
+  read and write operations are serialized. Extra left bits in AndData are\r
+  stripped.\r
+\r
+  If 64-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 63, then ASSERT().\r
+  If EndBit is greater than 63, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  AndData   The value to AND with value read from the MMIO register.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+MmioBitFieldAnd64 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT64                    AndData\r
+  )\r
+{\r
+  return MmioWrite64 (\r
+           Address,\r
+           BitFieldAnd64 (MmioRead64 (Address), StartBit, EndBit, AndData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND followed\r
+  by a bitwise OR, and writes the result back to the bit field in the\r
+  64-bit MMIO register.\r
+\r
+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND\r
+  followed by a bitwise OR between the read result and the value\r
+  specified by AndData, and writes the result to the 64-bit MMIO register\r
+  specified by Address. The value written to the MMIO register is returned.\r
+  This function must guarantee that all MMIO read and write operations are\r
+  serialized. Extra left bits in both AndData and OrData are stripped.\r
+\r
+  If 64-bit MMIO register operations are not supported, then ASSERT().\r
+  If StartBit is greater than 63, then ASSERT().\r
+  If EndBit is greater than 63, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   MMIO register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..63.\r
+  @param  AndData   The value to AND with value read from the MMIO register.\r
+  @param  OrData    The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the MMIO register.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+MmioBitFieldAndThenOr64 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT64                    AndData,\r
+  IN      UINT64                    OrData\r
+  )\r
+{\r
+  return MmioWrite64 (\r
+           Address,\r
+           BitFieldAndThenOr64 (MmioRead64 (Address), StartBit, EndBit, AndData, OrData)\r
+           );\r
+}\r
diff --git a/MdePkg/Library/DxeIoLibEsal/IoLib.c b/MdePkg/Library/DxeIoLibEsal/IoLib.c
new file mode 100644 (file)
index 0000000..7bc6ff1
--- /dev/null
@@ -0,0 +1,601 @@
+/** @file\r
+  I/O Library basic function implementation and worker functions.\r
+\r
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  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 "DxeIoLibEsalInternal.h"\r
+\r
+/**\r
+  Reads registers in the EFI CPU I/O space.\r
+\r
+  Reads the I/O port specified by Port with registers width specified by Width.\r
+  The read value is returned. If such operations are not supported, then ASSERT().\r
+  This function must guarantee that all I/O read and write operations are serialized.\r
+\r
+  @param  Port          The base address of the I/O operation.\r
+                        The caller is responsible for aligning the Address if required.\r
+  @param  Width         The width of the I/O operation.\r
+\r
+  @return Data read from registers in the EFI CPU I/O space.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+IoReadWorker (\r
+  IN      UINTN                     Port,\r
+  IN      EFI_CPU_IO_PROTOCOL_WIDTH Width\r
+  )\r
+{\r
+  SAL_RETURN_REGS  ReturnReg;\r
+  UINT64           Data;\r
+\r
+  ReturnReg = EsalCall (\r
+                EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID_LO,\r
+                EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID_HI,\r
+                IoReadFunctionId, \r
+                (UINT64)Width, \r
+                Port, \r
+                1, \r
+                (UINT64)&Data, \r
+                0, \r
+                0, \r
+                0\r
+                );\r
+  ASSERT (ReturnReg.Status == EFI_SAL_SUCCESS);\r
+  return Data;\r
+}\r
+\r
+/**\r
+  Writes registers in the EFI CPU I/O space.\r
+\r
+  Writes the I/O port specified by Port with registers width and value specified by Width\r
+  and Data respectively.  Data is returned. If such operations are not supported, then ASSERT().\r
+  This function must guarantee that all I/O read and write operations are serialized.\r
+\r
+  @param  Port          The base address of the I/O operation.\r
+                        The caller is responsible for aligning the Address if required.\r
+  @param  Width         The width of the I/O operation.\r
+  @param  Data          The value to write to the I/O port.\r
+\r
+  @return The paramter of Data.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+IoWriteWorker (\r
+  IN      UINTN                     Port,\r
+  IN      EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
+  IN      UINT64                    Data\r
+  )\r
+{\r
+  SAL_RETURN_REGS  ReturnReg;\r
+\r
+  ReturnReg = EsalCall (\r
+                EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID_LO,\r
+                EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID_HI,\r
+                IoWriteFunctionId, \r
+                (UINT64)Width, \r
+                Port, \r
+                1, \r
+                (UINT64)&Data, \r
+                0, \r
+                0, \r
+                0\r
+                );\r
+  ASSERT (ReturnReg.Status == EFI_SAL_SUCCESS);\r
+  return Data;\r
+}\r
+\r
+/**\r
+  Reads memory-mapped registers in the EFI system memory space.\r
+\r
+  Reads the MMIO registers specified by Address with registers width specified by Width.\r
+  The read value is returned. If such operations are not supported, then ASSERT().\r
+  This function must guarantee that all MMIO read and write operations are serialized.\r
+\r
+  @param  Address       The MMIO register to read.\r
+                        The caller is responsible for aligning the Address if required.\r
+  @param  Width         The width of the I/O operation.\r
+\r
+  @return Data read from registers in the EFI system memory space.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+MmioReadWorker (\r
+  IN      UINTN                     Address,\r
+  IN      EFI_CPU_IO_PROTOCOL_WIDTH Width\r
+  )\r
+{\r
+  SAL_RETURN_REGS  ReturnReg;\r
+  UINT64           Data;\r
+\r
+  ReturnReg = EsalCall (\r
+                EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID_LO,\r
+                EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID_HI,\r
+                MemReadFunctionId, \r
+                (UINT64)Width, \r
+                Address, \r
+                1, \r
+                (UINT64)&Data, \r
+                0, \r
+                0, \r
+                0\r
+                );\r
+  ASSERT (ReturnReg.Status == EFI_SAL_SUCCESS);\r
+  return Data;\r
+}\r
+\r
+/**\r
+  Writes memory-mapped registers in the EFI system memory space.\r
+\r
+  Writes the MMIO registers specified by Address with registers width and value specified by Width\r
+  and Data respectively. Data is returned. If such operations are not supported, then ASSERT().\r
+  This function must guarantee that all MMIO read and write operations are serialized.\r
+\r
+  @param  Address       The MMIO register to read.\r
+                        The caller is responsible for aligning the Address if required.\r
+  @param  Width         The width of the I/O operation.\r
+  @param  Data          The value to write to memory-mapped registers\r
+\r
+  @return Data read from registers in the EFI system memory space.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+MmioWriteWorker (\r
+  IN      UINTN                     Address,\r
+  IN      EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
+  IN      UINT64                    Data\r
+  )\r
+{\r
+  SAL_RETURN_REGS  ReturnReg;\r
+\r
+  ReturnReg = EsalCall (\r
+                EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID_LO,\r
+                EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID_HI,\r
+                MemWriteFunctionId, \r
+                (UINT64)Width, \r
+                Address, \r
+                1, \r
+                (UINT64)&Data, \r
+                0, \r
+                0, \r
+                0\r
+                );\r
+  ASSERT (ReturnReg.Status == EFI_SAL_SUCCESS);\r
+  return Data;\r
+}\r
+\r
+/**\r
+  Reads an 8-bit I/O port.\r
+\r
+  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.\r
+  This function must guarantee that all I/O read and write operations are\r
+  serialized.\r
+\r
+  If 8-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port  The I/O port to read.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+IoRead8 (\r
+  IN      UINTN                     Port\r
+  )\r
+{\r
+  return (UINT8)IoReadWorker (Port, EfiCpuIoWidthUint8);\r
+}\r
+\r
+/**\r
+  Writes an 8-bit I/O port.\r
+\r
+  Writes the 8-bit I/O port specified by Port with the value specified by Value\r
+  and returns Value. This function must guarantee that all I/O read and write\r
+  operations are serialized.\r
+\r
+  If 8-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port  The I/O port to write.\r
+  @param  Value The value to write to the I/O port.\r
+\r
+  @return The value written the I/O port.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+IoWrite8 (\r
+  IN      UINTN                     Port,\r
+  IN      UINT8                     Value\r
+  )\r
+{\r
+  return (UINT8)IoWriteWorker (Port, EfiCpuIoWidthUint8, Value);\r
+}\r
+\r
+/**\r
+  Reads a 16-bit I/O port.\r
+\r
+  Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.\r
+  This function must guarantee that all I/O read and write operations are\r
+  serialized.\r
+\r
+  If 16-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port  The I/O port to read.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+IoRead16 (\r
+  IN      UINTN                     Port\r
+  )\r
+{\r
+  //\r
+  // Make sure Port is aligned on a 16-bit boundary.\r
+  //\r
+  ASSERT ((Port & 1) == 0);\r
+  return (UINT16)IoReadWorker (Port, EfiCpuIoWidthUint16);\r
+}\r
+\r
+/**\r
+  Writes a 16-bit I/O port.\r
+\r
+  Writes the 16-bit I/O port specified by Port with the value specified by Value\r
+  and returns Value. This function must guarantee that all I/O read and write\r
+  operations are serialized.\r
+\r
+  If 16-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port  The I/O port to write.\r
+  @param  Value The value to write to the I/O port.\r
+\r
+  @return The value written the I/O port.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+IoWrite16 (\r
+  IN      UINTN                     Port,\r
+  IN      UINT16                    Value\r
+  )\r
+{\r
+  //\r
+  // Make sure Port is aligned on a 16-bit boundary.\r
+  //\r
+  ASSERT ((Port & 1) == 0);\r
+  return (UINT16)IoWriteWorker (Port, EfiCpuIoWidthUint16, Value);\r
+}\r
+\r
+/**\r
+  Reads a 32-bit I/O port.\r
+\r
+  Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.\r
+  This function must guarantee that all I/O read and write operations are\r
+  serialized.\r
+\r
+  If 32-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port  The I/O port to read.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+IoRead32 (\r
+  IN      UINTN                     Port\r
+  )\r
+{\r
+  //\r
+  // Make sure Port is aligned on a 32-bit boundary.\r
+  //\r
+  ASSERT ((Port & 3) == 0);\r
+  return (UINT32)IoReadWorker (Port, EfiCpuIoWidthUint32);\r
+}\r
+\r
+/**\r
+  Writes a 32-bit I/O port.\r
+\r
+  Writes the 32-bit I/O port specified by Port with the value specified by Value\r
+  and returns Value. This function must guarantee that all I/O read and write\r
+  operations are serialized.\r
+\r
+  If 32-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port  The I/O port to write.\r
+  @param  Value The value to write to the I/O port.\r
+\r
+  @return The value written the I/O port.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+IoWrite32 (\r
+  IN      UINTN                     Port,\r
+  IN      UINT32                    Value\r
+  )\r
+{\r
+  //\r
+  // Make sure Port is aligned on a 32-bit boundary.\r
+  //\r
+  ASSERT ((Port & 3) == 0);\r
+  return (UINT32)IoWriteWorker (Port, EfiCpuIoWidthUint32, Value);\r
+}\r
+\r
+/**\r
+  Reads a 64-bit I/O port.\r
+\r
+  Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.\r
+  This function must guarantee that all I/O read and write operations are\r
+  serialized.\r
+\r
+  If 64-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port  The I/O port to read.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+IoRead64 (\r
+  IN      UINTN                     Port\r
+  )\r
+{\r
+  //\r
+  // Make sure Port is aligned on a 64-bit boundary.\r
+  //\r
+  ASSERT ((Port & 7) == 0);\r
+  return IoReadWorker (Port, EfiCpuIoWidthUint64);\r
+}\r
+\r
+/**\r
+  Writes a 64-bit I/O port.\r
+\r
+  Writes the 64-bit I/O port specified by Port with the value specified by Value\r
+  and returns Value. This function must guarantee that all I/O read and write\r
+  operations are serialized.\r
+\r
+  If 64-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port  The I/O port to write.\r
+  @param  Value The value to write to the I/O port.\r
+\r
+  @return The value written the I/O port.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+IoWrite64 (\r
+  IN      UINTN                     Port,\r
+  IN      UINT64                    Value\r
+  )\r
+{\r
+  //\r
+  // Make sure Port is aligned on a 64-bit boundary.\r
+  //\r
+  ASSERT ((Port & 7) == 0);\r
+  return IoWriteWorker (Port, EfiCpuIoWidthUint64, Value);\r
+}\r
+\r
+/**\r
+  Reads an 8-bit MMIO register.\r
+\r
+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is\r
+  returned. This function must guarantee that all MMIO read and write\r
+  operations are serialized.\r
+\r
+  If 8-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+  @param  Address The MMIO register to read.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+MmioRead8 (\r
+  IN      UINTN                     Address\r
+  )\r
+{\r
+  return (UINT8)MmioReadWorker (Address, EfiCpuIoWidthUint8);\r
+}\r
+\r
+/**\r
+  Writes an 8-bit MMIO register.\r
+\r
+  Writes the 8-bit MMIO register specified by Address with the value specified\r
+  by Value and returns Value. This function must guarantee that all MMIO read\r
+  and write operations are serialized.\r
+\r
+  If 8-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+  @param  Address The MMIO register to write.\r
+  @param  Value   The value to write to the MMIO register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+MmioWrite8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT8                     Value\r
+  )\r
+{\r
+  return (UINT8)MmioWriteWorker (Address, EfiCpuIoWidthUint8, Value);\r
+}\r
+\r
+/**\r
+  Reads a 16-bit MMIO register.\r
+\r
+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is\r
+  returned. This function must guarantee that all MMIO read and write\r
+  operations are serialized.\r
+\r
+  If 16-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+  @param  Address The MMIO register to read.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+MmioRead16 (\r
+  IN      UINTN                     Address\r
+  )\r
+{\r
+  //\r
+  // Make sure Address is aligned on a 16-bit boundary.\r
+  //\r
+  ASSERT ((Address & 1) == 0);\r
+  return (UINT16)MmioReadWorker (Address, EfiCpuIoWidthUint16);\r
+}\r
+\r
+/**\r
+  Writes a 16-bit MMIO register.\r
+\r
+  Writes the 16-bit MMIO register specified by Address with the value specified\r
+  by Value and returns Value. This function must guarantee that all MMIO read\r
+  and write operations are serialized.\r
+\r
+  If 16-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+  @param  Address The MMIO register to write.\r
+  @param  Value   The value to write to the MMIO register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+MmioWrite16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT16                    Value\r
+  )\r
+{\r
+  //\r
+  // Make sure Address is aligned on a 16-bit boundary.\r
+  //\r
+  ASSERT ((Address & 1) == 0);\r
+  return (UINT16)MmioWriteWorker (Address, EfiCpuIoWidthUint16, Value);\r
+}\r
+\r
+/**\r
+  Reads a 32-bit MMIO register.\r
+\r
+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is\r
+  returned. This function must guarantee that all MMIO read and write\r
+  operations are serialized.\r
+\r
+  If 32-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+  @param  Address The MMIO register to read.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+MmioRead32 (\r
+  IN      UINTN                     Address\r
+  )\r
+{\r
+  //\r
+  // Make sure Address is aligned on a 32-bit boundary.\r
+  //\r
+  ASSERT ((Address & 3) == 0);\r
+  return (UINT32)MmioReadWorker (Address, EfiCpuIoWidthUint32);\r
+}\r
+\r
+/**\r
+  Writes a 32-bit MMIO register.\r
+\r
+  Writes the 32-bit MMIO register specified by Address with the value specified\r
+  by Value and returns Value. This function must guarantee that all MMIO read\r
+  and write operations are serialized.\r
+\r
+  If 32-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+  @param  Address The MMIO register to write.\r
+  @param  Value   The value to write to the MMIO register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+MmioWrite32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT32                    Value\r
+  )\r
+{\r
+  //\r
+  // Make sure Address is aligned on a 32-bit boundary.\r
+  //\r
+  ASSERT ((Address & 3) == 0);\r
+  return (UINT32)MmioWriteWorker (Address, EfiCpuIoWidthUint32, Value);\r
+}\r
+\r
+/**\r
+  Reads a 64-bit MMIO register.\r
+\r
+  Reads the 64-bit MMIO register specified by Address. The 64-bit read value is\r
+  returned. This function must guarantee that all MMIO read and write\r
+  operations are serialized.\r
+\r
+  If 64-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+  @param  Address The MMIO register to read.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+MmioRead64 (\r
+  IN      UINTN                     Address\r
+  )\r
+{\r
+  //\r
+  // Make sure Address is aligned on a 64-bit boundary.\r
+  //\r
+  ASSERT ((Address & 7) == 0);\r
+  return (UINT64)MmioReadWorker (Address, EfiCpuIoWidthUint64);\r
+}\r
+\r
+/**\r
+  Writes a 64-bit MMIO register.\r
+\r
+  Writes the 64-bit MMIO register specified by Address with the value specified\r
+  by Value and returns Value. This function must guarantee that all MMIO read\r
+  and write operations are serialized.\r
+\r
+  If 64-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+  @param  Address The MMIO register to write.\r
+  @param  Value   The value to write to the MMIO register.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+MmioWrite64 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT64                    Value\r
+  )\r
+{\r
+  //\r
+  // Make sure Address is aligned on a 64-bit boundary.\r
+  //\r
+  ASSERT ((Address & 7) == 0);\r
+  return (UINT64)MmioWriteWorker (Address, EfiCpuIoWidthUint64, Value);\r
+}\r
diff --git a/MdePkg/Library/DxeIoLibEsal/IoLibMmioBuffer.c b/MdePkg/Library/DxeIoLibEsal/IoLibMmioBuffer.c
new file mode 100644 (file)
index 0000000..5addef2
--- /dev/null
@@ -0,0 +1,411 @@
+/** @file\r
+  I/O Library MMIO Buffer Functions.\r
+\r
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  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 "DxeIoLibEsalInternal.h"\r
+\r
+/**\r
+  Copy data from MMIO region to system memory by using 8-bit access.\r
+\r
+  Copy data from MMIO region specified by starting address StartAddress \r
+  to system memory specified by Buffer by using 8-bit access. The total \r
+  number of byte to be copied is specified by Length. Buffer is returned.\r
+  \r
+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). \r
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
+\r
+\r
+  @param  StartAddress    Starting address for the MMIO region to be copied from.\r
+  @param  Length          Size in bytes of the copy.\r
+  @param  Buffer          Pointer to a system memory buffer receiving the data read.\r
+\r
+  @return Buffer\r
+\r
+**/\r
+UINT8 *\r
+EFIAPI\r
+MmioReadBuffer8 (\r
+  IN  UINTN       StartAddress,\r
+  IN  UINTN       Length,\r
+  OUT UINT8       *Buffer\r
+  )\r
+{\r
+  UINT8   *ReturnBuffer;\r
+\r
+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));\r
+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));\r
\r
+  ReturnBuffer = Buffer;\r
+  \r
+  while (Length-- > 0) {\r
+    *(Buffer++) = MmioRead8 (StartAddress++);\r
+  }\r
+\r
+  return ReturnBuffer;\r
+}\r
+\r
+/**\r
+  Copy data from MMIO region to system memory by using 16-bit access.\r
+\r
+  Copy data from MMIO region specified by starting address StartAddress \r
+  to system memory specified by Buffer by using 16-bit access. The total \r
+  number of byte to be copied is specified by Length. Buffer is returned.\r
+  \r
+  If StartAddress is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). \r
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
+\r
+  If Length is not aligned on a 16-bit boundary, then ASSERT().\r
+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  StartAddress    Starting address for the MMIO region to be copied from.\r
+  @param  Length          Size in bytes of the copy.\r
+  @param  Buffer          Pointer to a system memory buffer receiving the data read.\r
+\r
+  @return Buffer\r
+\r
+**/\r
+UINT16 *\r
+EFIAPI\r
+MmioReadBuffer16 (\r
+  IN  UINTN       StartAddress,\r
+  IN  UINTN       Length,\r
+  OUT UINT16      *Buffer\r
+  )\r
+{\r
+  UINT16    *ReturnBuffer;\r
+\r
+  ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0);\r
+  \r
+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));\r
+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));\r
+\r
+  ASSERT ((Length & (sizeof (UINT16) - 1)) == 0);\r
+  ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0);\r
\r
+  ReturnBuffer = Buffer;\r
+  \r
+  while (Length > 0) {\r
+    *(Buffer++) = MmioRead16 (StartAddress);\r
+    StartAddress += sizeof (UINT16);\r
+    Length -= sizeof (UINT16);\r
+  }\r
+\r
+  return ReturnBuffer;\r
+}\r
+\r
+/**\r
+  Copy data from MMIO region to system memory by using 32-bit access.\r
+\r
+  Copy data from MMIO region specified by starting address StartAddress \r
+  to system memory specified by Buffer by using 32-bit access. The total \r
+  number of byte to be copied is specified by Length. Buffer is returned.\r
+  \r
+  If StartAddress is not aligned on a 32-bit boundary, then ASSERT().\r
+\r
+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). \r
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
+\r
+  If Length is not aligned on a 32-bit boundary, then ASSERT().\r
+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().\r
+\r
+  @param  StartAddress    Starting address for the MMIO region to be copied from.\r
+  @param  Length          Size in bytes of the copy.\r
+  @param  Buffer          Pointer to a system memory buffer receiving the data read.\r
+\r
+  @return Buffer\r
+\r
+**/\r
+UINT32 *\r
+EFIAPI\r
+MmioReadBuffer32 (\r
+  IN  UINTN       StartAddress,\r
+  IN  UINTN       Length,\r
+  OUT UINT32      *Buffer\r
+  )\r
+{\r
+  UINT32    *ReturnBuffer;\r
+\r
+  ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);\r
+  \r
+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));\r
+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));\r
+\r
+  ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);\r
+  ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);\r
\r
+  ReturnBuffer = Buffer;\r
+  \r
+  while (Length > 0) {\r
+    *(Buffer++) = MmioRead32 (StartAddress);\r
+    StartAddress += sizeof (UINT32);\r
+    Length -= sizeof (UINT32);\r
+  }\r
+\r
+  return ReturnBuffer;\r
+}\r
+\r
+/**\r
+  Copy data from MMIO region to system memory by using 64-bit access.\r
+\r
+  Copy data from MMIO region specified by starting address StartAddress \r
+  to system memory specified by Buffer by using 64-bit access. The total \r
+  number of byte to be copied is specified by Length. Buffer is returned.\r
+  \r
+  If StartAddress is not aligned on a 64-bit boundary, then ASSERT().\r
+\r
+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). \r
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
+\r
+  If Length is not aligned on a 64-bit boundary, then ASSERT().\r
+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().\r
+\r
+  @param  StartAddress    Starting address for the MMIO region to be copied from.\r
+  @param  Length          Size in bytes of the copy.\r
+  @param  Buffer          Pointer to a system memory buffer receiving the data read.\r
+\r
+  @return Buffer\r
+\r
+**/\r
+UINT64 *\r
+EFIAPI\r
+MmioReadBuffer64 (\r
+  IN  UINTN       StartAddress,\r
+  IN  UINTN       Length,\r
+  OUT UINT64      *Buffer\r
+  )\r
+{\r
+  UINT64    *ReturnBuffer;\r
+\r
+  ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0);\r
+  \r
+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));\r
+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));\r
+\r
+  ASSERT ((Length & (sizeof (UINT64) - 1)) == 0);\r
+  ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0);\r
\r
+  ReturnBuffer = Buffer;\r
+  \r
+  while (Length > 0) {\r
+    *(Buffer++) = MmioRead64 (StartAddress);\r
+    StartAddress += sizeof (UINT64);\r
+    Length -= sizeof (UINT64);\r
+  }\r
+\r
+  return ReturnBuffer;\r
+}\r
+\r
+\r
+/**\r
+  Copy data from system memory to MMIO region by using 8-bit access.\r
+\r
+  Copy data from system memory specified by Buffer to MMIO region specified \r
+  by starting address StartAddress by using 8-bit access. The total number \r
+  of byte to be copied is specified by Length. Buffer is returned.\r
+  \r
+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). \r
+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().\r
+\r
+\r
+  @param  StartAddress    Starting address for the MMIO region to be copied to.\r
+  @param  Length     Size in bytes of the copy.\r
+  @param  Buffer          Pointer to a system memory buffer containing the data to write.\r
+\r
+  @return Buffer\r
+\r
+**/\r
+UINT8 *\r
+EFIAPI\r
+MmioWriteBuffer8 (\r
+  IN  UINTN         StartAddress,\r
+  IN  UINTN         Length,\r
+  IN  CONST UINT8   *Buffer\r
+  )\r
+{\r
+  VOID* ReturnBuffer;\r
+\r
+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));\r
+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));\r
\r
+  ReturnBuffer = (UINT8 *) Buffer;\r
+  \r
+  while (Length-- > 0) {\r
+     MmioWrite8 (StartAddress++, *(Buffer++));\r
+  }\r
+\r
+  return ReturnBuffer;\r
\r
+}\r
+\r
+/**\r
+  Copy data from system memory to MMIO region by using 16-bit access.\r
+\r
+  Copy data from system memory specified by Buffer to MMIO region specified \r
+  by starting address StartAddress by using 16-bit access. The total number \r
+  of byte to be copied is specified by Length. Buffer is returned.\r
+  \r
+  If StartAddress is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). \r
+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().\r
+\r
+  If Length is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  StartAddress    Starting address for the MMIO region to be copied to.\r
+  @param  Length     Size in bytes of the copy.\r
+  @param  Buffer          Pointer to a system memory buffer containing the data to write.\r
+\r
+  @return Buffer\r
+\r
+**/\r
+UINT16 *\r
+EFIAPI\r
+MmioWriteBuffer16 (\r
+  IN  UINTN        StartAddress,\r
+  IN  UINTN        Length,\r
+  IN  CONST UINT16 *Buffer\r
+  )\r
+{\r
+  UINT16    *ReturnBuffer;\r
+\r
+  ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0);\r
+  \r
+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));\r
+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));\r
+\r
+  ASSERT ((Length & (sizeof (UINT16) - 1)) == 0);\r
+  ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0);\r
+\r
+  ReturnBuffer = (UINT16 *) Buffer;\r
+  \r
+  while (Length > 0) {\r
+    MmioWrite16 (StartAddress, *(Buffer++));\r
+    \r
+    StartAddress += sizeof (UINT16);\r
+    Length -= sizeof (UINT16);\r
+  }\r
+\r
+  return ReturnBuffer;\r
+}\r
+\r
+\r
+/**\r
+  Copy data from system memory to MMIO region by using 32-bit access.\r
+\r
+  Copy data from system memory specified by Buffer to MMIO region specified \r
+  by starting address StartAddress by using 32-bit access. The total number \r
+  of byte to be copied is specified by Length. Buffer is returned.\r
+  \r
+  If StartAddress is not aligned on a 32-bit boundary, then ASSERT().\r
+\r
+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). \r
+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().\r
+\r
+  If Length is not aligned on a 32-bit boundary, then ASSERT().\r
+\r
+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().\r
+\r
+  @param  StartAddress    Starting address for the MMIO region to be copied to.\r
+  @param  Length     Size in bytes of the copy.\r
+  @param  Buffer          Pointer to a system memory buffer containing the data to write.\r
+\r
+  @return Buffer\r
+\r
+**/\r
+UINT32 *\r
+EFIAPI\r
+MmioWriteBuffer32 (\r
+  IN  UINTN        StartAddress,\r
+  IN  UINTN        Length,\r
+  IN  CONST UINT32 *Buffer\r
+  )\r
+{\r
+  UINT32    *ReturnBuffer;\r
+\r
+  ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);\r
+  \r
+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));\r
+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));\r
+\r
+  ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);\r
+  ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);\r
+\r
+  ReturnBuffer = (UINT32 *) Buffer;\r
+  \r
+  while (Length > 0) {\r
+    MmioWrite32 (StartAddress, *(Buffer++));\r
+    \r
+    StartAddress += sizeof (UINT32);\r
+    Length -= sizeof (UINT32);\r
+  }\r
+\r
+  return ReturnBuffer;\r
+}\r
+\r
+/**\r
+  Copy data from system memory to MMIO region by using 64-bit access.\r
+\r
+  Copy data from system memory specified by Buffer to MMIO region specified \r
+  by starting address StartAddress by using 64-bit access. The total number \r
+  of byte to be copied is specified by Length. Buffer is returned.\r
+  \r
+  If StartAddress is not aligned on a 64-bit boundary, then ASSERT().\r
+\r
+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). \r
+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().\r
+\r
+  If Length is not aligned on a 64-bit boundary, then ASSERT().\r
+\r
+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().\r
+\r
+  @param  StartAddress    Starting address for the MMIO region to be copied to.\r
+  @param  Length     Size in bytes of the copy.\r
+  @param  Buffer          Pointer to a system memory buffer containing the data to write.\r
+\r
+  @return Buffer\r
+\r
+**/\r
+UINT64 *\r
+EFIAPI\r
+MmioWriteBuffer64 (\r
+  IN  UINTN        StartAddress,\r
+  IN  UINTN        Length,\r
+  IN  CONST UINT64 *Buffer\r
+  )\r
+{\r
+  UINT64    *ReturnBuffer;\r
+\r
+  ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0);\r
+  \r
+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));\r
+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));\r
+\r
+  ASSERT ((Length & (sizeof (UINT64) - 1)) == 0);\r
+  ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0);\r
+\r
+  ReturnBuffer = (UINT64 *) Buffer;\r
+  \r
+  while (Length > 0) {\r
+    MmioWrite64 (StartAddress, *(Buffer++));\r
+    \r
+    StartAddress += sizeof (UINT64);\r
+    Length -= sizeof (UINT64);\r
+  }\r
+\r
+  return ReturnBuffer;\r
+}\r
+\r
diff --git a/MdePkg/Library/DxePalLibEsal/DxePalLibEsal.c b/MdePkg/Library/DxePalLibEsal/DxePalLibEsal.c
new file mode 100644 (file)
index 0000000..6500320
--- /dev/null
@@ -0,0 +1,73 @@
+/** @file\r
+  PAL Library Class implementation built upon Extended SAL Procedures.\r
+\r
+  Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  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 <PiDxe.h>\r
+\r
+#include <Protocol/ExtendedSalServiceClasses.h>\r
+\r
+#include <Library/PalLib.h>\r
+#include <Library/ExtendedSalLib.h>\r
+\r
+/**\r
+  Makes a PAL procedure call.\r
+\r
+  This is a wrapper function to make a PAL procedure call.  Based on the Index value,\r
+  this API will make static or stacked PAL call. Architected procedures may be designated\r
+  as required or optional.  If a PAL procedure is specified as optional, a unique return\r
+  code of 0xFFFFFFFFFFFFFFFF is returned in the Status field of the PAL_CALL_RETURN structure.\r
+  This indicates that the procedure is not present in this PAL implementation.  It is the\r
+  caller's responsibility to check for this return code after calling any optional PAL\r
+  procedure. No parameter checking is performed on the 4 input parameters, but there are\r
+  some common rules that the caller should follow when making a PAL call.  Any address\r
+  passed to PAL as buffers for return parameters must be 8-byte aligned.  Unaligned addresses\r
+  may cause undefined results.  For those parameters defined as reserved or some fields\r
+  defined as reserved must be zero filled or the invalid argument return value may be\r
+  returned or undefined result may occur during the execution of the procedure.\r
+  This function is only available on IPF.\r
+\r
+  @param Index - The PAL procedure Index number.\r
+  @param Arg2  - The 2nd parameter for PAL procedure calls.\r
+  @param Arg3  - The 3rd parameter for PAL procedure calls.\r
+  @param Arg4  - The 4th parameter for PAL procedure calls.\r
+\r
+  @return structure returned from the PAL Call procedure, including the status and return value.\r
+\r
+**/\r
+PAL_CALL_RETURN\r
+EFIAPI\r
+PalCall (\r
+  IN UINT64                  Index,\r
+  IN UINT64                  Arg2,\r
+  IN UINT64                  Arg3,\r
+  IN UINT64                  Arg4\r
+  )\r
+{\r
+  SAL_RETURN_REGS SalReturn;\r
+  PAL_CALL_RETURN *PalReturn;\r
+\r
+  SalReturn = EsalCall (\r
+                EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO,\r
+                EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,\r
+                PalProcFunctionId, \r
+                Index, \r
+                Arg2, \r
+                Arg3, \r
+                Arg4, \r
+                0, \r
+                0, \r
+                0\r
+                );\r
+  PalReturn = (PAL_CALL_RETURN *) (UINTN) (&SalReturn);\r
+  return *PalReturn;\r
+}\r
diff --git a/MdePkg/Library/DxePalLibEsal/DxePalLibEsal.inf b/MdePkg/Library/DxePalLibEsal/DxePalLibEsal.inf
new file mode 100644 (file)
index 0000000..4c0abbc
--- /dev/null
@@ -0,0 +1,39 @@
+## @file\r
+#  Instance of PAL Library Class using Extended SAL functions\r
+#\r
+#  Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  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
+#  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
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DxePalLibEsal\r
+  FILE_GUID                      = 8BA65DE3-39E1-4afd-A8FE-7DD0BAFEFCC0\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = PalLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION \r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IPF\r
+#\r
+\r
+[Sources.IPF]\r
+  DxePalLibEsal.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+  ExtendedSalLib\r
+\r
+[Depex]\r
+  gEfiExtendedSalPalServicesProtocolGuid\r
diff --git a/MdePkg/Library/DxePciLibEsal/DxePciLibEsal.inf b/MdePkg/Library/DxePciLibEsal/DxePciLibEsal.inf
new file mode 100644 (file)
index 0000000..8d349c9
--- /dev/null
@@ -0,0 +1,38 @@
+## @file\r
+#  PCI Library that uses ESAL services to perform PCI Configuration cycles.\r
+#\r
+#  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  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
+#  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
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DxePciLibEsal\r
+  FILE_GUID                      = E3441740-3B41-4c90-9C9D-964056C7417D\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = PciLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IPF\r
+#\r
+\r
+[Sources]\r
+  PciLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+  ExtendedSalLib\r
+  DebugLib\r
+  BaseLib\r
diff --git a/MdePkg/Library/DxePciLibEsal/PciLib.c b/MdePkg/Library/DxePciLibEsal/PciLib.c
new file mode 100644 (file)
index 0000000..8cc1a50
--- /dev/null
@@ -0,0 +1,1449 @@
+/** @file\r
+  DXE PCI Library instance layered on top of ESAL services.\r
+\r
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  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 <PiDxe.h>\r
+\r
+#include <Protocol/ExtendedSalServiceClasses.h>\r
+\r
+#include <Library/PciLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/ExtendedSalLib.h>\r
+\r
+/**\r
+  Assert the validity of a PCI address. A valid PCI address should contain 1's\r
+  only in the low 28 bits.\r
+\r
+  @param  A The address to validate.\r
+  @param  M Additional bits to assert to be zero.\r
+\r
+**/\r
+#define ASSERT_INVALID_PCI_ADDRESS(A,M) \\r
+  ASSERT (((A) & (~0xfffffff | (M))) == 0)\r
+\r
+/**\r
+  Converts a PCI Library Address to a ESAL PCI Service Address.\r
+  Based on SAL Spec 3.2, there are two SAL PCI Address:\r
+\r
+  If address type = 0\r
+  Bits 0..7 - Register address\r
+  Bits 8..10 - Function number\r
+  Bits 11..15 - Device number\r
+  Bits 16..23 - Bus number\r
+  Bits 24..31 - PCI segment group\r
+  Bits 32..63 - Reserved (0)\r
+\r
+  If address type = 1\r
+  Bits 0..7 - Register address\r
+  Bits 8..11 - Extended Register address\r
+  Bits 12..14 - Function number\r
+  Bits 15..19 - Device number\r
+  Bits 20..27 - Bus number\r
+  Bits 28..43 - PCI segment group\r
+  Bits 44..63 - Reserved (0)\r
+\r
+  @param  A The PCI Library Address to convert.\r
+\r
+**/\r
+#define CONVERT_PCI_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS0(Address)  ((((Address) >> 4) & 0x00ffff00) | ((Address) & 0xff))\r
+#define CONVERT_PCI_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS1(Address)  (Address)\r
+\r
+/**\r
+  Check a PCI Library Address is a PCI Compatible Address or not.\r
+**/\r
+#define IS_PCI_COMPATIBLE_ADDRESS(Address)  (((Address) & 0xf00) == 0)\r
+\r
+/**\r
+  Internal worker function to read a PCI configuration register.\r
+\r
+  This function wraps EsalPciConfigRead function of Extended SAL PCI\r
+  Services Class.\r
+  It reads and returns the PCI configuration register specified by Address,\r
+  the width of data is specified by Width.\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+  @param  Width   Width of data to read\r
+\r
+  @return The value read from the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+DxePciLibEsalReadWorker (\r
+  IN    UINTN                       Address,\r
+  IN    UINTN                       Width\r
+  )\r
+{\r
+ SAL_RETURN_REGS Return;\r
+\r
+  if (IS_PCI_COMPATIBLE_ADDRESS(Address)) {\r
+    Return = EsalCall (\r
+               EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,\r
+               EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,\r
+               SalPciConfigReadFunctionId,\r
+               CONVERT_PCI_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS0 (Address),\r
+               Width,\r
+               EFI_SAL_PCI_COMPATIBLE_ADDRESS,\r
+               0,\r
+               0,\r
+               0,\r
+               0\r
+               );\r
+  } else {\r
+    Return = EsalCall (\r
+               EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,\r
+               EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,\r
+               SalPciConfigReadFunctionId,\r
+               CONVERT_PCI_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS1 (Address),\r
+               Width,\r
+               EFI_SAL_PCI_EXTENDED_REGISTER_ADDRESS,\r
+               0,\r
+               0,\r
+               0,\r
+               0\r
+               );\r
+  }\r
+\r
+  return (UINT32) Return.r9;\r
+}\r
+\r
+/**\r
+  Internal worker function to writes a PCI configuration register.\r
+\r
+  This function wraps EsalPciConfigWrite function of Extended SAL PCI\r
+  Services Class.\r
+  It writes the PCI configuration register specified by Address with the\r
+  value specified by Data. The width of data is specifed by Width.\r
+  Data is returned.\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+  @param  Width   Width of data to write\r
+  @param  Data    The value to write.\r
+\r
+  @return The value written to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+DxePciLibEsalWriteWorker (\r
+  IN    UINTN                       Address,\r
+  IN    UINTN                       Width,\r
+  IN    UINT32                      Data\r
+  )\r
+{\r
+  if (IS_PCI_COMPATIBLE_ADDRESS(Address)) {\r
+    EsalCall (\r
+      EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,\r
+      EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,\r
+      SalPciConfigWriteFunctionId,\r
+      CONVERT_PCI_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS0 (Address),\r
+      Width,\r
+      Data,\r
+      EFI_SAL_PCI_COMPATIBLE_ADDRESS,\r
+      0,\r
+      0,\r
+      0\r
+      );\r
+  } else {\r
+    EsalCall (\r
+      EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,\r
+      EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,\r
+      SalPciConfigWriteFunctionId,\r
+      CONVERT_PCI_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS1 (Address),\r
+      Width,\r
+      Data,\r
+      EFI_SAL_PCI_EXTENDED_REGISTER_ADDRESS,\r
+      0,\r
+      0,\r
+      0\r
+      );\r
+  }\r
+\r
+  return Data;\r
+}\r
+\r
+/**\r
+  Register a PCI device so PCI configuration registers may be accessed after\r
+  SetVirtualAddressMap().\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+\r
+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.\r
+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function\r
+                                   after ExitBootServices().\r
+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device\r
+                                   at runtime could not be mapped.\r
+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to\r
+                                   complete the registration.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+PciRegisterForRuntimeAccess (\r
+  IN UINTN  Address\r
+  )\r
+{\r
+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Reads an 8-bit PCI configuration register.\r
+\r
+  Reads and returns the 8-bit PCI configuration register specified by Address.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+\r
+  @return The value read from the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciRead8 (\r
+  IN      UINTN                     Address\r
+  )\r
+{\r
+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
+\r
+  return (UINT8) DxePciLibEsalReadWorker (Address, 1);\r
+}\r
+\r
+/**\r
+  Writes an 8-bit PCI configuration register.\r
+\r
+  Writes the 8-bit PCI configuration register specified by Address with the\r
+  value specified by Value. Value is returned. This function must guarantee\r
+  that all PCI read and write operations are serialized.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+  @param  Data    The value to write.\r
+\r
+  @return The value written to the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciWrite8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT8                     Data\r
+  )\r
+{\r
+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);\r
+\r
+  return (UINT8) DxePciLibEsalWriteWorker (Address, 1, Data);\r
+}\r
+\r
+/**\r
+  Performs a bitwise OR of an 8-bit PCI configuration register with\r
+  an 8-bit value.\r
+\r
+  Reads the 8-bit PCI configuration register specified by Address, performs a\r
+  bitwise OR between the read result and the value specified by\r
+  OrData, and writes the result to the 8-bit PCI configuration register\r
+  specified by Address. The value written to the PCI configuration register is\r
+  returned. This function must guarantee that all PCI read and write operations\r
+  are serialized.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+  @param  OrData  The value to OR with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciOr8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT8                     OrData\r
+  )\r
+{\r
+  return PciWrite8 (Address, (UINT8)(PciRead8 (Address) | OrData));\r
+}\r
+\r
+/**\r
+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit\r
+  value.\r
+\r
+  Reads the 8-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData, and\r
+  writes the result to the 8-bit PCI configuration register specified by\r
+  Address. The value written to the PCI configuration register is returned.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+  @param  AndData The value to AND with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciAnd8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT8                     AndData\r
+  )\r
+{\r
+  return PciWrite8 (Address, (UINT8)(PciRead8 (Address) & AndData));\r
+}\r
+\r
+/**\r
+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit\r
+  value, followed a  bitwise OR with another 8-bit value.\r
+\r
+  Reads the 8-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData,\r
+  performs a bitwise OR between the result of the AND operation and\r
+  the value specified by OrData, and writes the result to the 8-bit PCI\r
+  configuration register specified by Address. The value written to the PCI\r
+  configuration register is returned. This function must guarantee that all PCI\r
+  read and write operations are serialized.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+  @param  AndData The value to AND with the PCI configuration register.\r
+  @param  OrData  The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciAndThenOr8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT8                     AndData,\r
+  IN      UINT8                     OrData\r
+  )\r
+{\r
+  return PciWrite8 (Address, (UINT8)((PciRead8 (Address) & AndData) | OrData));\r
+}\r
+\r
+/**\r
+  Reads a bit field of a PCI configuration register.\r
+\r
+  Reads the bit field in an 8-bit PCI configuration register. The bit field is\r
+  specified by the StartBit and the EndBit. The value of the bit field is\r
+  returned.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to read.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+\r
+  @return The value of the bit field read from the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciBitFieldRead8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit\r
+  )\r
+{\r
+  return BitFieldRead8 (PciRead8 (Address), StartBit, EndBit);\r
+}\r
+\r
+/**\r
+  Writes a bit field to a PCI configuration register.\r
+\r
+  Writes Value to the bit field of the PCI configuration register. The bit\r
+  field is specified by the StartBit and the EndBit. All other bits in the\r
+  destination PCI configuration register are preserved. The new value of the\r
+  8-bit register is returned.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  Value     New value of the bit field.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciBitFieldWrite8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT8                     Value\r
+  )\r
+{\r
+  return PciWrite8 (\r
+           Address,\r
+           BitFieldWrite8 (PciRead8 (Address), StartBit, EndBit, Value)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and\r
+  writes the result back to the bit field in the 8-bit port.\r
+\r
+  Reads the 8-bit PCI configuration register specified by Address, performs a\r
+  bitwise OR between the read result and the value specified by\r
+  OrData, and writes the result to the 8-bit PCI configuration register\r
+  specified by Address. The value written to the PCI configuration register is\r
+  returned. This function must guarantee that all PCI read and write operations\r
+  are serialized. Extra left bits in OrData are stripped.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  OrData    The value to OR with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciBitFieldOr8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT8                     OrData\r
+  )\r
+{\r
+  return PciWrite8 (\r
+           Address,\r
+           BitFieldOr8 (PciRead8 (Address), StartBit, EndBit, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise\r
+  AND, and writes the result back to the bit field in the 8-bit register.\r
+\r
+  Reads the 8-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData, and\r
+  writes the result to the 8-bit PCI configuration register specified by\r
+  Address. The value written to the PCI configuration register is returned.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized. Extra left bits in AndData are stripped.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  AndData   The value to AND with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciBitFieldAnd8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT8                     AndData\r
+  )\r
+{\r
+  return PciWrite8 (\r
+           Address,\r
+           BitFieldAnd8 (PciRead8 (Address), StartBit, EndBit, AndData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a\r
+  bitwise OR, and writes the result back to the bit field in the\r
+  8-bit port.\r
+\r
+  Reads the 8-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND followed by a bitwise OR between the read result and\r
+  the value specified by AndData, and writes the result to the 8-bit PCI\r
+  configuration register specified by Address. The value written to the PCI\r
+  configuration register is returned. This function must guarantee that all PCI\r
+  read and write operations are serialized. Extra left bits in both AndData and\r
+  OrData are stripped.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  AndData   The value to AND with the PCI configuration register.\r
+  @param  OrData    The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciBitFieldAndThenOr8 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT8                     AndData,\r
+  IN      UINT8                     OrData\r
+  )\r
+{\r
+  return PciWrite8 (\r
+           Address,\r
+           BitFieldAndThenOr8 (PciRead8 (Address), StartBit, EndBit, AndData, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a 16-bit PCI configuration register.\r
+\r
+  Reads and returns the 16-bit PCI configuration register specified by Address.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+\r
+  @return The value read from the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciRead16 (\r
+  IN      UINTN                     Address\r
+  )\r
+{\r
+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
+\r
+  return (UINT16) DxePciLibEsalReadWorker (Address, 2);\r
+}\r
+\r
+/**\r
+  Writes a 16-bit PCI configuration register.\r
+\r
+  Writes the 16-bit PCI configuration register specified by Address with the\r
+  value specified by Value. Value is returned. This function must guarantee\r
+  that all PCI read and write operations are serialized.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+  @param  Data    The value to write.\r
+\r
+  @return The value written to the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciWrite16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT16                    Data\r
+  )\r
+{\r
+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);\r
+\r
+  return (UINT16) DxePciLibEsalWriteWorker (Address, 2, Data);\r
+}\r
+\r
+/**\r
+  Performs a bitwise OR of a 16-bit PCI configuration register with\r
+  a 16-bit value.\r
+\r
+  Reads the 16-bit PCI configuration register specified by Address, performs a\r
+  bitwise OR between the read result and the value specified by\r
+  OrData, and writes the result to the 16-bit PCI configuration register\r
+  specified by Address. The value written to the PCI configuration register is\r
+  returned. This function must guarantee that all PCI read and write operations\r
+  are serialized.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+  @param  OrData  The value to OR with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciOr16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT16                    OrData\r
+  )\r
+{\r
+  return PciWrite16 (Address, (UINT16)(PciRead16 (Address) | OrData));\r
+}\r
+\r
+/**\r
+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r
+  value.\r
+\r
+  Reads the 16-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData, and\r
+  writes the result to the 16-bit PCI configuration register specified by\r
+  Address. The value written to the PCI configuration register is returned.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+  @param  AndData The value to AND with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciAnd16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT16                    AndData\r
+  )\r
+{\r
+  return PciWrite16 (Address, (UINT16)(PciRead16 (Address) & AndData));\r
+}\r
+\r
+/**\r
+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r
+  value, followed a  bitwise OR with another 16-bit value.\r
+\r
+  Reads the 16-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData,\r
+  performs a bitwise OR between the result of the AND operation and\r
+  the value specified by OrData, and writes the result to the 16-bit PCI\r
+  configuration register specified by Address. The value written to the PCI\r
+  configuration register is returned. This function must guarantee that all PCI\r
+  read and write operations are serialized.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+  @param  AndData The value to AND with the PCI configuration register.\r
+  @param  OrData  The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciAndThenOr16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT16                    AndData,\r
+  IN      UINT16                    OrData\r
+  )\r
+{\r
+  return PciWrite16 (Address, (UINT16)((PciRead16 (Address) & AndData) | OrData));\r
+}\r
+\r
+/**\r
+  Reads a bit field of a PCI configuration register.\r
+\r
+  Reads the bit field in a 16-bit PCI configuration register. The bit field is\r
+  specified by the StartBit and the EndBit. The value of the bit field is\r
+  returned.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 16-bit boundary, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to read.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+\r
+  @return The value of the bit field read from the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciBitFieldRead16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit\r
+  )\r
+{\r
+  return BitFieldRead16 (PciRead16 (Address), StartBit, EndBit);\r
+}\r
+\r
+/**\r
+  Writes a bit field to a PCI configuration register.\r
+\r
+  Writes Value to the bit field of the PCI configuration register. The bit\r
+  field is specified by the StartBit and the EndBit. All other bits in the\r
+  destination PCI configuration register are preserved. The new value of the\r
+  16-bit register is returned.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 16-bit boundary, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  Value     New value of the bit field.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciBitFieldWrite16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT16                    Value\r
+  )\r
+{\r
+  return PciWrite16 (\r
+           Address,\r
+           BitFieldWrite16 (PciRead16 (Address), StartBit, EndBit, Value)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and\r
+  writes the result back to the bit field in the 16-bit port.\r
+\r
+  Reads the 16-bit PCI configuration register specified by Address, performs a\r
+  bitwise OR between the read result and the value specified by\r
+  OrData, and writes the result to the 16-bit PCI configuration register\r
+  specified by Address. The value written to the PCI configuration register is\r
+  returned. This function must guarantee that all PCI read and write operations\r
+  are serialized. Extra left bits in OrData are stripped.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 16-bit boundary, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  OrData    The value to OR with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciBitFieldOr16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT16                    OrData\r
+  )\r
+{\r
+  return PciWrite16 (\r
+           Address,\r
+           BitFieldOr16 (PciRead16 (Address), StartBit, EndBit, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise\r
+  AND, and writes the result back to the bit field in the 16-bit register.\r
+\r
+  Reads the 16-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData, and\r
+  writes the result to the 16-bit PCI configuration register specified by\r
+  Address. The value written to the PCI configuration register is returned.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized. Extra left bits in AndData are stripped.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 16-bit boundary, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  AndData   The value to AND with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciBitFieldAnd16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT16                    AndData\r
+  )\r
+{\r
+  return PciWrite16 (\r
+           Address,\r
+           BitFieldAnd16 (PciRead16 (Address), StartBit, EndBit, AndData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a\r
+  bitwise OR, and writes the result back to the bit field in the\r
+  16-bit port.\r
+\r
+  Reads the 16-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND followed by a bitwise OR between the read result and\r
+  the value specified by AndData, and writes the result to the 16-bit PCI\r
+  configuration register specified by Address. The value written to the PCI\r
+  configuration register is returned. This function must guarantee that all PCI\r
+  read and write operations are serialized. Extra left bits in both AndData and\r
+  OrData are stripped.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 16-bit boundary, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  AndData   The value to AND with the PCI configuration register.\r
+  @param  OrData    The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciBitFieldAndThenOr16 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT16                    AndData,\r
+  IN      UINT16                    OrData\r
+  )\r
+{\r
+  return PciWrite16 (\r
+           Address,\r
+           BitFieldAndThenOr16 (PciRead16 (Address), StartBit, EndBit, AndData, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a 32-bit PCI configuration register.\r
+\r
+  Reads and returns the 32-bit PCI configuration register specified by Address.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 32-bit boundary, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+\r
+  @return The value read from the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciRead32 (\r
+  IN      UINTN                     Address\r
+  )\r
+{\r
+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
+\r
+  return DxePciLibEsalReadWorker (Address, 4);\r
+}\r
+\r
+/**\r
+  Writes a 32-bit PCI configuration register.\r
+\r
+  Writes the 32-bit PCI configuration register specified by Address with the\r
+  value specified by Value. Value is returned. This function must guarantee\r
+  that all PCI read and write operations are serialized.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 32-bit boundary, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+  @param  Data    The value to write.\r
+\r
+  @return The value written to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciWrite32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT32                    Data\r
+  )\r
+{\r
+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);\r
+\r
+  return DxePciLibEsalWriteWorker (Address, 4, Data);\r
+}\r
+\r
+/**\r
+  Performs a bitwise OR of a 32-bit PCI configuration register with\r
+  a 32-bit value.\r
+\r
+  Reads the 32-bit PCI configuration register specified by Address, performs a\r
+  bitwise OR between the read result and the value specified by\r
+  OrData, and writes the result to the 32-bit PCI configuration register\r
+  specified by Address. The value written to the PCI configuration register is\r
+  returned. This function must guarantee that all PCI read and write operations\r
+  are serialized.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 32-bit boundary, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+  @param  OrData  The value to OR with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciOr32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT32                    OrData\r
+  )\r
+{\r
+  return PciWrite32 (Address, PciRead32 (Address) | OrData);\r
+}\r
+\r
+/**\r
+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r
+  value.\r
+\r
+  Reads the 32-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData, and\r
+  writes the result to the 32-bit PCI configuration register specified by\r
+  Address. The value written to the PCI configuration register is returned.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 32-bit boundary, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+  @param  AndData The value to AND with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciAnd32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT32                    AndData\r
+  )\r
+{\r
+  return PciWrite32 (Address, PciRead32 (Address) & AndData);\r
+}\r
+\r
+/**\r
+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r
+  value, followed a  bitwise OR with another 32-bit value.\r
+\r
+  Reads the 32-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData,\r
+  performs a bitwise OR between the result of the AND operation and\r
+  the value specified by OrData, and writes the result to the 32-bit PCI\r
+  configuration register specified by Address. The value written to the PCI\r
+  configuration register is returned. This function must guarantee that all PCI\r
+  read and write operations are serialized.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 32-bit boundary, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+  @param  AndData The value to AND with the PCI configuration register.\r
+  @param  OrData  The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciAndThenOr32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINT32                    AndData,\r
+  IN      UINT32                    OrData\r
+  )\r
+{\r
+  return PciWrite32 (Address, (PciRead32 (Address) & AndData) | OrData);\r
+}\r
+\r
+/**\r
+  Reads a bit field of a PCI configuration register.\r
+\r
+  Reads the bit field in a 32-bit PCI configuration register. The bit field is\r
+  specified by the StartBit and the EndBit. The value of the bit field is\r
+  returned.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 32-bit boundary, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to read.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+\r
+  @return The value of the bit field read from the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciBitFieldRead32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit\r
+  )\r
+{\r
+  return BitFieldRead32 (PciRead32 (Address), StartBit, EndBit);\r
+}\r
+\r
+/**\r
+  Writes a bit field to a PCI configuration register.\r
+\r
+  Writes Value to the bit field of the PCI configuration register. The bit\r
+  field is specified by the StartBit and the EndBit. All other bits in the\r
+  destination PCI configuration register are preserved. The new value of the\r
+  32-bit register is returned.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 32-bit boundary, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  Value     New value of the bit field.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciBitFieldWrite32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT32                    Value\r
+  )\r
+{\r
+  return PciWrite32 (\r
+           Address,\r
+           BitFieldWrite32 (PciRead32 (Address), StartBit, EndBit, Value)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and\r
+  writes the result back to the bit field in the 32-bit port.\r
+\r
+  Reads the 32-bit PCI configuration register specified by Address, performs a\r
+  bitwise OR between the read result and the value specified by\r
+  OrData, and writes the result to the 32-bit PCI configuration register\r
+  specified by Address. The value written to the PCI configuration register is\r
+  returned. This function must guarantee that all PCI read and write operations\r
+  are serialized. Extra left bits in OrData are stripped.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 32-bit boundary, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  OrData    The value to OR with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciBitFieldOr32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT32                    OrData\r
+  )\r
+{\r
+  return PciWrite32 (\r
+           Address,\r
+           BitFieldOr32 (PciRead32 (Address), StartBit, EndBit, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise\r
+  AND, and writes the result back to the bit field in the 32-bit register.\r
+\r
+  Reads the 32-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData, and\r
+  writes the result to the 32-bit PCI configuration register specified by\r
+  Address. The value written to the PCI configuration register is returned.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized. Extra left bits in AndData are stripped.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 32-bit boundary, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  AndData   The value to AND with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciBitFieldAnd32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT32                    AndData\r
+  )\r
+{\r
+  return PciWrite32 (\r
+           Address,\r
+           BitFieldAnd32 (PciRead32 (Address), StartBit, EndBit, AndData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a\r
+  bitwise OR, and writes the result back to the bit field in the\r
+  32-bit port.\r
+\r
+  Reads the 32-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND followed by a bitwise OR between the read result and\r
+  the value specified by AndData, and writes the result to the 32-bit PCI\r
+  configuration register specified by Address. The value written to the PCI\r
+  configuration register is returned. This function must guarantee that all PCI\r
+  read and write operations are serialized. Extra left bits in both AndData and\r
+  OrData are stripped.\r
+\r
+  If Address > 0x0FFFFFFF, then ASSERT().\r
+  If Address is not aligned on a 32-bit boundary, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  AndData   The value to AND with the PCI configuration register.\r
+  @param  OrData    The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciBitFieldAndThenOr32 (\r
+  IN      UINTN                     Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT32                    AndData,\r
+  IN      UINT32                    OrData\r
+  )\r
+{\r
+  return PciWrite32 (\r
+           Address,\r
+           BitFieldAndThenOr32 (PciRead32 (Address), StartBit, EndBit, AndData, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a range of PCI configuration registers into a caller supplied buffer.\r
+\r
+  Reads the range of PCI configuration registers specified by StartAddress and\r
+  Size into the buffer specified by Buffer. This function only allows the PCI\r
+  configuration registers from a single PCI function to be read. Size is\r
+  returned. When possible 32-bit PCI configuration read cycles are used to read\r
+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit\r
+  and 16-bit PCI configuration read cycles may be used at the beginning and the\r
+  end of the range.\r
+\r
+  If StartAddress > 0x0FFFFFFF, then ASSERT().\r
+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
+  If Size > 0 and Buffer is NULL, then ASSERT().\r
+\r
+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,\r
+                        Function and Register.\r
+  @param  Size          Size in bytes of the transfer.\r
+  @param  Buffer        Pointer to a buffer receiving the data read.\r
+\r
+  @return Size\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+PciReadBuffer (\r
+  IN      UINTN                     StartAddress,\r
+  IN      UINTN                     Size,\r
+  OUT     VOID                      *Buffer\r
+  )\r
+{\r
+  UINTN                             ReturnValue;\r
+\r
+  ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);\r
+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);\r
+\r
+  if (Size == 0) {\r
+    return Size;\r
+  }\r
+\r
+  ASSERT (Buffer != NULL);\r
+\r
+  //\r
+  // Save Size for return\r
+  //\r
+  ReturnValue = Size;\r
+\r
+  if ((StartAddress & 1) != 0) {\r
+    //\r
+    // Read a byte if StartAddress is byte aligned\r
+    //\r
+    *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);\r
+    StartAddress += sizeof (UINT8);\r
+    Size -= sizeof (UINT8);\r
+    Buffer = (UINT8*)Buffer + 1;\r
+  }\r
+\r
+  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {\r
+    //\r
+    // Read a word if StartAddress is word aligned\r
+    //\r
+    *(volatile UINT16 *)Buffer = PciRead16 (StartAddress);\r
+    StartAddress += sizeof (UINT16);\r
+    Size -= sizeof (UINT16);\r
+    Buffer = (UINT16*)Buffer + 1;\r
+  }\r
+\r
+  while (Size >= sizeof (UINT32)) {\r
+    //\r
+    // Read as many double words as possible\r
+    //\r
+    *(volatile UINT32 *)Buffer = PciRead32 (StartAddress);\r
+    StartAddress += sizeof (UINT32);\r
+    Size -= sizeof (UINT32);\r
+    Buffer = (UINT32*)Buffer + 1;\r
+  }\r
+\r
+  if (Size >= sizeof (UINT16)) {\r
+    //\r
+    // Read the last remaining word if exist\r
+    //\r
+    *(volatile UINT16 *)Buffer = PciRead16 (StartAddress);\r
+    StartAddress += sizeof (UINT16);\r
+    Size -= sizeof (UINT16);\r
+    Buffer = (UINT16*)Buffer + 1;\r
+  }\r
+\r
+  if (Size >= sizeof (UINT8)) {\r
+    //\r
+    // Read the last remaining byte if exist\r
+    //\r
+    *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);\r
+  }\r
+\r
+  return ReturnValue;\r
+}\r
+\r
+/**\r
+  Copies the data in a caller supplied buffer to a specified range of PCI\r
+  configuration space.\r
+\r
+  Writes the range of PCI configuration registers specified by StartAddress and\r
+  Size from the buffer specified by Buffer. This function only allows the PCI\r
+  configuration registers from a single PCI function to be written. Size is\r
+  returned. When possible 32-bit PCI configuration write cycles are used to\r
+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,\r
+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning\r
+  and the end of the range.\r
+\r
+  If StartAddress > 0x0FFFFFFF, then ASSERT().\r
+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
+  If Size > 0 and Buffer is NULL, then ASSERT().\r
+\r
+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,\r
+                        Function and Register.\r
+  @param  Size          Size in bytes of the transfer.\r
+  @param  Buffer        Pointer to a buffer containing the data to write.\r
+\r
+  @return Size\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+PciWriteBuffer (\r
+  IN      UINTN                     StartAddress,\r
+  IN      UINTN                     Size,\r
+  IN      VOID                      *Buffer\r
+  )\r
+{\r
+  UINTN                             ReturnValue;\r
+\r
+  ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);\r
+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);\r
+\r
+  if (Size == 0) {\r
+    return 0;\r
+  }\r
+\r
+  ASSERT (Buffer != NULL);\r
+\r
+  //\r
+  // Save Size for return\r
+  //\r
+  ReturnValue = Size;\r
+\r
+  if ((StartAddress & 1) != 0) {\r
+    //\r
+    // Write a byte if StartAddress is byte aligned\r
+    //\r
+    PciWrite8 (StartAddress, *(UINT8*)Buffer);\r
+    StartAddress += sizeof (UINT8);\r
+    Size -= sizeof (UINT8);\r
+    Buffer = (UINT8*)Buffer + 1;\r
+  }\r
+\r
+  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {\r
+    //\r
+    // Write a word if StartAddress is word aligned\r
+    //\r
+    PciWrite16 (StartAddress, *(UINT16*)Buffer);\r
+    StartAddress += sizeof (UINT16);\r
+    Size -= sizeof (UINT16);\r
+    Buffer = (UINT16*)Buffer + 1;\r
+  }\r
+\r
+  while (Size >= sizeof (UINT32)) {\r
+    //\r
+    // Write as many double words as possible\r
+    //\r
+    PciWrite32 (StartAddress, *(UINT32*)Buffer);\r
+    StartAddress += sizeof (UINT32);\r
+    Size -= sizeof (UINT32);\r
+    Buffer = (UINT32*)Buffer + 1;\r
+  }\r
+\r
+  if (Size >= sizeof (UINT16)) {\r
+    //\r
+    // Write the last remaining word if exist\r
+    //\r
+    PciWrite16 (StartAddress, *(UINT16*)Buffer);\r
+    StartAddress += sizeof (UINT16);\r
+    Size -= sizeof (UINT16);\r
+    Buffer = (UINT16*)Buffer + 1;\r
+  }\r
+\r
+  if (Size >= sizeof (UINT8)) {\r
+    //\r
+    // Write the last remaining byte if exist\r
+    //\r
+    PciWrite8 (StartAddress, *(UINT8*)Buffer);\r
+  }\r
+\r
+  return ReturnValue;\r
+}\r
diff --git a/MdePkg/Library/DxePciSegmentLibEsal/DxePciSegmentLibEsal.inf b/MdePkg/Library/DxePciSegmentLibEsal/DxePciSegmentLibEsal.inf
new file mode 100644 (file)
index 0000000..6799ef4
--- /dev/null
@@ -0,0 +1,38 @@
+## @file\r
+#  PCI Segment Library that uses ESAL services to perform PCI Configuration cycles.\r
+#\r
+#  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  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
+#  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
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DxePciSegementLibEsal\r
+  FILE_GUID                      = 6D497A7A-D7DA-467c-B485-B7FB3493C41F\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = PciSegmentLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IPF\r
+#\r
+\r
+[Sources]\r
+  PciLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+  ExtendedSalLib\r
+  DebugLib\r
+  BaseLib\r
diff --git a/MdePkg/Library/DxePciSegmentLibEsal/PciLib.c b/MdePkg/Library/DxePciSegmentLibEsal/PciLib.c
new file mode 100644 (file)
index 0000000..a7572a0
--- /dev/null
@@ -0,0 +1,1401 @@
+/** @file\r
+  DXE PCI Segment Library instance layered on top of ESAL services.\r
+\r
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  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 <PiDxe.h>\r
+\r
+#include <Protocol/ExtendedSalServiceClasses.h>\r
+\r
+#include <Library/PciSegmentLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/ExtendedSalLib.h>\r
+\r
+/**\r
+  Assert the validity of a PCI Segment address.\r
+  A valid PCI Segment address should not contain 1's in bits 31:28\r
+\r
+  @param  A The address to validate.\r
+  @param  M Additional bits to assert to be zero.\r
+\r
+**/\r
+#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \\r
+  ASSERT (((A) & (0xf0000000 | (M))) == 0)\r
+\r
+/**\r
+  Converts a PCI Library Address to a ESAL PCI Service Address.\r
+  Based on SAL Spec 3.2, there are two SAL PCI Address:\r
+\r
+  If address type = 0\r
+  Bits 0..7 - Register address\r
+  Bits 8..10 - Function number\r
+  Bits 11..15 - Device number\r
+  Bits 16..23 - Bus number\r
+  Bits 24..31 - PCI segment group\r
+  Bits 32..63 - Reserved (0)\r
+\r
+  If address type = 1\r
+  Bits 0..7 - Register address\r
+  Bits 8..11 - Extended Register address\r
+  Bits 12..14 - Function number\r
+  Bits 15..19 - Device number\r
+  Bits 20..27 - Bus number\r
+  Bits 28..43 - PCI segment group\r
+  Bits 44..63 - Reserved (0)\r
+\r
+  @param  A The PCI Library Address to convert.\r
+\r
+**/\r
+#define CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS0(Address)  (((Address >> 8) & 0xff000000) | (((Address) >> 4) & 0x00ffff00) | ((Address) & 0xff))\r
+#define CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS1(Address)  (((Address >> 4) & 0xffff0000000) | ((Address) & 0xfffffff))\r
+\r
+/**\r
+  Check a PCI Library Address is a PCI Compatible Address or not.\r
+**/\r
+#define IS_PCI_COMPATIBLE_ADDRESS(Address)  (((Address) & 0xf00) == 0)\r
+\r
+/**\r
+  Internal worker function to read a PCI configuration register.\r
+\r
+  This function wraps EsalPciConfigRead function of Extended SAL PCI\r
+  Services Class.\r
+  It reads and returns the PCI configuration register specified by Address,\r
+  the width of data is specified by Width.\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+  @param  Width   Width of data to read\r
+\r
+  @return The value read from the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+DxePciSegmentLibEsalReadWorker (\r
+  IN  UINT64        Address,\r
+  IN  UINTN         Width\r
+  )\r
+{\r
+  SAL_RETURN_REGS Return;\r
+\r
+  if (IS_PCI_COMPATIBLE_ADDRESS(Address)) {\r
+    Return = EsalCall (\r
+               EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,\r
+               EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,\r
+               SalPciConfigReadFunctionId,\r
+               CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS0 (Address),\r
+               Width,\r
+               EFI_SAL_PCI_COMPATIBLE_ADDRESS,\r
+               0,\r
+               0,\r
+               0,\r
+               0\r
+               );\r
+  } else {\r
+    Return = EsalCall (\r
+               EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,\r
+               EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,\r
+               SalPciConfigReadFunctionId,\r
+               CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS1 (Address),\r
+               Width,\r
+               EFI_SAL_PCI_EXTENDED_REGISTER_ADDRESS,\r
+               0,\r
+               0,\r
+               0,\r
+               0\r
+               );\r
+  }\r
+\r
+  return (UINT32) Return.r9;\r
+}\r
+\r
+/**\r
+  Internal worker function to writes a PCI configuration register.\r
+\r
+  This function wraps EsalPciConfigWrite function of Extended SAL PCI\r
+  Services Class.\r
+  It writes the PCI configuration register specified by Address with the\r
+  value specified by Data. The width of data is specifed by Width.\r
+  Data is returned.\r
+\r
+  @param  Address Address that encodes the PCI Bus, Device, Function and\r
+                  Register.\r
+  @param  Width   Width of data to write\r
+  @param  Data    The value to write.\r
+\r
+  @return The value written to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+DxePciSegmentLibEsalWriteWorker (\r
+  IN  UINT64           Address,\r
+  IN  UINTN            Width,\r
+  IN  UINT32           Data\r
+  )\r
+{\r
+  if (IS_PCI_COMPATIBLE_ADDRESS(Address)) {\r
+    EsalCall (\r
+      EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,\r
+      EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,\r
+      SalPciConfigWriteFunctionId,\r
+      CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS0 (Address),\r
+      Width,\r
+      Data,\r
+      EFI_SAL_PCI_COMPATIBLE_ADDRESS,\r
+      0,\r
+      0,\r
+      0\r
+      );\r
+  } else {\r
+    EsalCall (\r
+      EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,\r
+      EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,\r
+      SalPciConfigWriteFunctionId,\r
+      CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS1 (Address),\r
+      Width,\r
+      Data,\r
+      EFI_SAL_PCI_EXTENDED_REGISTER_ADDRESS,\r
+      0,\r
+      0,\r
+      0\r
+      );\r
+  }\r
+\r
+  return Data;\r
+}\r
+\r
+/**\r
+  Reads an 8-bit PCI configuration register.\r
+\r
+  Reads and returns the 8-bit PCI configuration register specified by Address.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and\r
+                  Register.\r
+\r
+  @return The value read from the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciSegmentRead8 (\r
+  IN      UINT64                    Address\r
+  )\r
+{\r
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);\r
+\r
+  return (UINT8) DxePciSegmentLibEsalReadWorker (Address, 1);\r
+}\r
+\r
+/**\r
+  Writes an 8-bit PCI configuration register.\r
+\r
+  Writes the 8-bit PCI configuration register specified by Address with the\r
+  value specified by Value. Value is returned. This function must guarantee\r
+  that all PCI read and write operations are serialized.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and\r
+                  Register.\r
+  @param  Data    The value to write.\r
+\r
+  @return The value written to the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciSegmentWrite8 (\r
+  IN      UINT64                    Address,\r
+  IN      UINT8                     Data\r
+  )\r
+{\r
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);\r
+\r
+  return (UINT8) DxePciSegmentLibEsalWriteWorker (Address, 1, Data);\r
+}\r
+\r
+/**\r
+  Performs a bitwise OR of an 8-bit PCI configuration register with\r
+  an 8-bit value.\r
+\r
+  Reads the 8-bit PCI configuration register specified by Address, performs a\r
+  bitwise OR between the read result and the value specified by\r
+  OrData, and writes the result to the 8-bit PCI configuration register\r
+  specified by Address. The value written to the PCI configuration register is\r
+  returned. This function must guarantee that all PCI read and write operations\r
+  are serialized.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and\r
+                  Register.\r
+  @param  OrData  The value to OR with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciSegmentOr8 (\r
+  IN      UINT64                    Address,\r
+  IN      UINT8                     OrData\r
+  )\r
+{\r
+  return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (Address) | OrData));\r
+}\r
+\r
+/**\r
+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit\r
+  value.\r
+\r
+  Reads the 8-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData, and\r
+  writes the result to the 8-bit PCI configuration register specified by\r
+  Address. The value written to the PCI configuration register is returned.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and\r
+                  Register.\r
+  @param  AndData The value to AND with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciSegmentAnd8 (\r
+  IN      UINT64                    Address,\r
+  IN      UINT8                     AndData\r
+  )\r
+{\r
+  return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (Address) & AndData));\r
+}\r
+\r
+/**\r
+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit\r
+  value, followed a  bitwise OR with another 8-bit value.\r
+\r
+  Reads the 8-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData,\r
+  performs a bitwise OR between the result of the AND operation and\r
+  the value specified by OrData, and writes the result to the 8-bit PCI\r
+  configuration register specified by Address. The value written to the PCI\r
+  configuration register is returned. This function must guarantee that all PCI\r
+  read and write operations are serialized.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and\r
+                  Register.\r
+  @param  AndData The value to AND with the PCI configuration register.\r
+  @param  OrData  The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciSegmentAndThenOr8 (\r
+  IN      UINT64                    Address,\r
+  IN      UINT8                     AndData,\r
+  IN      UINT8                     OrData\r
+  )\r
+{\r
+  return PciSegmentWrite8 (Address, (UINT8) ((PciSegmentRead8 (Address) & AndData) | OrData));\r
+}\r
+\r
+/**\r
+  Reads a bit field of a PCI configuration register.\r
+\r
+  Reads the bit field in an 8-bit PCI configuration register. The bit field is\r
+  specified by the StartBit and the EndBit. The value of the bit field is\r
+  returned.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to read.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+\r
+  @return The value of the bit field read from the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciSegmentBitFieldRead8 (\r
+  IN      UINT64                    Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit\r
+  )\r
+{\r
+  return BitFieldRead8 (PciSegmentRead8 (Address), StartBit, EndBit);\r
+}\r
+\r
+/**\r
+  Writes a bit field to a PCI configuration register.\r
+\r
+  Writes Value to the bit field of the PCI configuration register. The bit\r
+  field is specified by the StartBit and the EndBit. All other bits in the\r
+  destination PCI configuration register are preserved. The new value of the\r
+  8-bit register is returned.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  Value     New value of the bit field.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciSegmentBitFieldWrite8 (\r
+  IN      UINT64                    Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT8                     Value\r
+  )\r
+{\r
+  return PciSegmentWrite8 (\r
+           Address,\r
+           BitFieldWrite8 (PciSegmentRead8 (Address), StartBit, EndBit, Value)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and\r
+  writes the result back to the bit field in the 8-bit port.\r
+\r
+  Reads the 8-bit PCI configuration register specified by Address, performs a\r
+  bitwise OR between the read result and the value specified by\r
+  OrData, and writes the result to the 8-bit PCI configuration register\r
+  specified by Address. The value written to the PCI configuration register is\r
+  returned. This function must guarantee that all PCI read and write operations\r
+  are serialized. Extra left bits in OrData are stripped.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  OrData    The value to OR with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciSegmentBitFieldOr8 (\r
+  IN      UINT64                    Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT8                     OrData\r
+  )\r
+{\r
+  return PciSegmentWrite8 (\r
+           Address,\r
+           BitFieldOr8 (PciSegmentRead8 (Address), StartBit, EndBit, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise\r
+  AND, and writes the result back to the bit field in the 8-bit register.\r
+\r
+  Reads the 8-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData, and\r
+  writes the result to the 8-bit PCI configuration register specified by\r
+  Address. The value written to the PCI configuration register is returned.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized. Extra left bits in AndData are stripped.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  AndData   The value to AND with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciSegmentBitFieldAnd8 (\r
+  IN      UINT64                    Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT8                     AndData\r
+  )\r
+{\r
+  return PciSegmentWrite8 (\r
+           Address,\r
+           BitFieldAnd8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a\r
+  bitwise OR, and writes the result back to the bit field in the\r
+  8-bit port.\r
+\r
+  Reads the 8-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND followed by a bitwise OR between the read result and\r
+  the value specified by AndData, and writes the result to the 8-bit PCI\r
+  configuration register specified by Address. The value written to the PCI\r
+  configuration register is returned. This function must guarantee that all PCI\r
+  read and write operations are serialized. Extra left bits in both AndData and\r
+  OrData are stripped.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+  If StartBit is greater than 7, then ASSERT().\r
+  If EndBit is greater than 7, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..7.\r
+  @param  AndData   The value to AND with the PCI configuration register.\r
+  @param  OrData    The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+PciSegmentBitFieldAndThenOr8 (\r
+  IN      UINT64                    Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT8                     AndData,\r
+  IN      UINT8                     OrData\r
+  )\r
+{\r
+  return PciSegmentWrite8 (\r
+           Address,\r
+           BitFieldAndThenOr8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a 16-bit PCI configuration register.\r
+\r
+  Reads and returns the 16-bit PCI configuration register specified by Address.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and\r
+                  Register.\r
+\r
+  @return The value read from the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciSegmentRead16 (\r
+  IN      UINT64                    Address\r
+  )\r
+{\r
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);\r
+\r
+  return (UINT16) DxePciSegmentLibEsalReadWorker (Address, 2);\r
+}\r
+\r
+/**\r
+  Writes a 16-bit PCI configuration register.\r
+\r
+  Writes the 16-bit PCI configuration register specified by Address with the\r
+  value specified by Value. Value is returned. This function must guarantee\r
+  that all PCI read and write operations are serialized.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and\r
+                  Register.\r
+  @param  Data    The value to write.\r
+\r
+  @return The value written to the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciSegmentWrite16 (\r
+  IN      UINT64                    Address,\r
+  IN      UINT16                    Data\r
+  )\r
+{\r
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);\r
+\r
+  return (UINT16) DxePciSegmentLibEsalWriteWorker (Address, 2, Data);\r
+}\r
+\r
+/**\r
+  Performs a bitwise OR of a 16-bit PCI configuration register with\r
+  a 16-bit value.\r
+\r
+  Reads the 16-bit PCI configuration register specified by Address, performs a\r
+  bitwise OR between the read result and the value specified by\r
+  OrData, and writes the result to the 16-bit PCI configuration register\r
+  specified by Address. The value written to the PCI configuration register is\r
+  returned. This function must guarantee that all PCI read and write operations\r
+  are serialized.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and\r
+                  Register.\r
+  @param  OrData  The value to OR with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciSegmentOr16 (\r
+  IN      UINT64                    Address,\r
+  IN      UINT16                    OrData\r
+  )\r
+{\r
+  return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) | OrData));\r
+}\r
+\r
+/**\r
+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r
+  value.\r
+\r
+  Reads the 16-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData, and\r
+  writes the result to the 16-bit PCI configuration register specified by\r
+  Address. The value written to the PCI configuration register is returned.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and\r
+                  Register.\r
+  @param  AndData The value to AND with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciSegmentAnd16 (\r
+  IN      UINT64                    Address,\r
+  IN      UINT16                    AndData\r
+  )\r
+{\r
+  return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) & AndData));\r
+}\r
+\r
+/**\r
+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit\r
+  value, followed a  bitwise OR with another 16-bit value.\r
+\r
+  Reads the 16-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData,\r
+  performs a bitwise OR between the result of the AND operation and\r
+  the value specified by OrData, and writes the result to the 16-bit PCI\r
+  configuration register specified by Address. The value written to the PCI\r
+  configuration register is returned. This function must guarantee that all PCI\r
+  read and write operations are serialized.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and\r
+                  Register.\r
+  @param  AndData The value to AND with the PCI configuration register.\r
+  @param  OrData  The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciSegmentAndThenOr16 (\r
+  IN      UINT64                    Address,\r
+  IN      UINT16                    AndData,\r
+  IN      UINT16                    OrData\r
+  )\r
+{\r
+  return PciSegmentWrite16 (Address, (UINT16) ((PciSegmentRead16 (Address) & AndData) | OrData));\r
+}\r
+\r
+/**\r
+  Reads a bit field of a PCI configuration register.\r
+\r
+  Reads the bit field in a 16-bit PCI configuration register. The bit field is\r
+  specified by the StartBit and the EndBit. The value of the bit field is\r
+  returned.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to read.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+\r
+  @return The value of the bit field read from the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciSegmentBitFieldRead16 (\r
+  IN      UINT64                    Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit\r
+  )\r
+{\r
+  return BitFieldRead16 (PciSegmentRead16 (Address), StartBit, EndBit);\r
+}\r
+\r
+/**\r
+  Writes a bit field to a PCI configuration register.\r
+\r
+  Writes Value to the bit field of the PCI configuration register. The bit\r
+  field is specified by the StartBit and the EndBit. All other bits in the\r
+  destination PCI configuration register are preserved. The new value of the\r
+  16-bit register is returned.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  Value     New value of the bit field.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciSegmentBitFieldWrite16 (\r
+  IN      UINT64                    Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT16                    Value\r
+  )\r
+{\r
+  return PciSegmentWrite16 (\r
+           Address,\r
+           BitFieldWrite16 (PciSegmentRead16 (Address), StartBit, EndBit, Value)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and\r
+  writes the result back to the bit field in the 16-bit port.\r
+\r
+  Reads the 16-bit PCI configuration register specified by Address, performs a\r
+  bitwise OR between the read result and the value specified by\r
+  OrData, and writes the result to the 16-bit PCI configuration register\r
+  specified by Address. The value written to the PCI configuration register is\r
+  returned. This function must guarantee that all PCI read and write operations\r
+  are serialized. Extra left bits in OrData are stripped.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  OrData    The value to OR with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciSegmentBitFieldOr16 (\r
+  IN      UINT64                    Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT16                    OrData\r
+  )\r
+{\r
+  return PciSegmentWrite16 (\r
+           Address,\r
+           BitFieldOr16 (PciSegmentRead16 (Address), StartBit, EndBit, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise\r
+  AND, and writes the result back to the bit field in the 16-bit register.\r
+\r
+  Reads the 16-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData, and\r
+  writes the result to the 16-bit PCI configuration register specified by\r
+  Address. The value written to the PCI configuration register is returned.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized. Extra left bits in AndData are stripped.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  AndData   The value to AND with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciSegmentBitFieldAnd16 (\r
+  IN      UINT64                    Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT16                    AndData\r
+  )\r
+{\r
+  return PciSegmentWrite16 (\r
+           Address,\r
+           BitFieldAnd16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a\r
+  bitwise OR, and writes the result back to the bit field in the\r
+  16-bit port.\r
+\r
+  Reads the 16-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND followed by a bitwise OR between the read result and\r
+  the value specified by AndData, and writes the result to the 16-bit PCI\r
+  configuration register specified by Address. The value written to the PCI\r
+  configuration register is returned. This function must guarantee that all PCI\r
+  read and write operations are serialized. Extra left bits in both AndData and\r
+  OrData are stripped.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+  If StartBit is greater than 15, then ASSERT().\r
+  If EndBit is greater than 15, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..15.\r
+  @param  AndData   The value to AND with the PCI configuration register.\r
+  @param  OrData    The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PciSegmentBitFieldAndThenOr16 (\r
+  IN      UINT64                    Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT16                    AndData,\r
+  IN      UINT16                    OrData\r
+  )\r
+{\r
+  return PciSegmentWrite16 (\r
+           Address,\r
+           BitFieldAndThenOr16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a 32-bit PCI configuration register.\r
+\r
+  Reads and returns the 32-bit PCI configuration register specified by Address.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and\r
+                  Register.\r
+\r
+  @return The value read from the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciSegmentRead32 (\r
+  IN      UINT64                    Address\r
+  )\r
+{\r
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);\r
+\r
+  return DxePciSegmentLibEsalReadWorker (Address, 4);\r
+}\r
+\r
+/**\r
+  Writes a 32-bit PCI configuration register.\r
+\r
+  Writes the 32-bit PCI configuration register specified by Address with the\r
+  value specified by Value. Value is returned. This function must guarantee\r
+  that all PCI read and write operations are serialized.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and\r
+                  Register.\r
+  @param  Data    The value to write.\r
+\r
+  @return The value written to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciSegmentWrite32 (\r
+  IN      UINT64                    Address,\r
+  IN      UINT32                    Data\r
+  )\r
+{\r
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);\r
+\r
+  return DxePciSegmentLibEsalWriteWorker (Address, 4, Data);\r
+}\r
+\r
+/**\r
+  Performs a bitwise OR of a 32-bit PCI configuration register with\r
+  a 32-bit value.\r
+\r
+  Reads the 32-bit PCI configuration register specified by Address, performs a\r
+  bitwise OR between the read result and the value specified by\r
+  OrData, and writes the result to the 32-bit PCI configuration register\r
+  specified by Address. The value written to the PCI configuration register is\r
+  returned. This function must guarantee that all PCI read and write operations\r
+  are serialized.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and\r
+                  Register.\r
+  @param  OrData  The value to OR with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciSegmentOr32 (\r
+  IN      UINT64                    Address,\r
+  IN      UINT32                    OrData\r
+  )\r
+{\r
+  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) | OrData);\r
+}\r
+\r
+/**\r
+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r
+  value.\r
+\r
+  Reads the 32-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData, and\r
+  writes the result to the 32-bit PCI configuration register specified by\r
+  Address. The value written to the PCI configuration register is returned.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and\r
+                  Register.\r
+  @param  AndData The value to AND with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciSegmentAnd32 (\r
+  IN      UINT64                    Address,\r
+  IN      UINT32                    AndData\r
+  )\r
+{\r
+  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) & AndData);\r
+}\r
+\r
+/**\r
+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit\r
+  value, followed a  bitwise OR with another 32-bit value.\r
+\r
+  Reads the 32-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData,\r
+  performs a bitwise OR between the result of the AND operation and\r
+  the value specified by OrData, and writes the result to the 32-bit PCI\r
+  configuration register specified by Address. The value written to the PCI\r
+  configuration register is returned. This function must guarantee that all PCI\r
+  read and write operations are serialized.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+\r
+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and\r
+                  Register.\r
+  @param  AndData The value to AND with the PCI configuration register.\r
+  @param  OrData  The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciSegmentAndThenOr32 (\r
+  IN      UINT64                    Address,\r
+  IN      UINT32                    AndData,\r
+  IN      UINT32                    OrData\r
+  )\r
+{\r
+  return PciSegmentWrite32 (Address, (PciSegmentRead32 (Address) & AndData) | OrData);\r
+}\r
+\r
+/**\r
+  Reads a bit field of a PCI configuration register.\r
+\r
+  Reads the bit field in a 32-bit PCI configuration register. The bit field is\r
+  specified by the StartBit and the EndBit. The value of the bit field is\r
+  returned.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to read.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+\r
+  @return The value of the bit field read from the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciSegmentBitFieldRead32 (\r
+  IN      UINT64                    Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit\r
+  )\r
+{\r
+  return BitFieldRead32 (PciSegmentRead32 (Address), StartBit, EndBit);\r
+}\r
+\r
+/**\r
+  Writes a bit field to a PCI configuration register.\r
+\r
+  Writes Value to the bit field of the PCI configuration register. The bit\r
+  field is specified by the StartBit and the EndBit. All other bits in the\r
+  destination PCI configuration register are preserved. The new value of the\r
+  32-bit register is returned.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  Value     New value of the bit field.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciSegmentBitFieldWrite32 (\r
+  IN      UINT64                    Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT32                    Value\r
+  )\r
+{\r
+  return PciSegmentWrite32 (\r
+           Address,\r
+           BitFieldWrite32 (PciSegmentRead32 (Address), StartBit, EndBit, Value)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and\r
+  writes the result back to the bit field in the 32-bit port.\r
+\r
+  Reads the 32-bit PCI configuration register specified by Address, performs a\r
+  bitwise OR between the read result and the value specified by\r
+  OrData, and writes the result to the 32-bit PCI configuration register\r
+  specified by Address. The value written to the PCI configuration register is\r
+  returned. This function must guarantee that all PCI read and write operations\r
+  are serialized. Extra left bits in OrData are stripped.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  OrData    The value to OR with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciSegmentBitFieldOr32 (\r
+  IN      UINT64                    Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT32                    OrData\r
+  )\r
+{\r
+  return PciSegmentWrite32 (\r
+           Address,\r
+           BitFieldOr32 (PciSegmentRead32 (Address), StartBit, EndBit, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise\r
+  AND, and writes the result back to the bit field in the 32-bit register.\r
+\r
+  Reads the 32-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND between the read result and the value specified by AndData, and\r
+  writes the result to the 32-bit PCI configuration register specified by\r
+  Address. The value written to the PCI configuration register is returned.\r
+  This function must guarantee that all PCI read and write operations are\r
+  serialized. Extra left bits in AndData are stripped.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  AndData   The value to AND with the PCI configuration register.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciSegmentBitFieldAnd32 (\r
+  IN      UINT64                    Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT32                    AndData\r
+  )\r
+{\r
+  return PciSegmentWrite32 (\r
+           Address,\r
+           BitFieldAnd32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a\r
+  bitwise OR, and writes the result back to the bit field in the\r
+  32-bit port.\r
+\r
+  Reads the 32-bit PCI configuration register specified by Address, performs a\r
+  bitwise AND followed by a bitwise OR between the read result and\r
+  the value specified by AndData, and writes the result to the 32-bit PCI\r
+  configuration register specified by Address. The value written to the PCI\r
+  configuration register is returned. This function must guarantee that all PCI\r
+  read and write operations are serialized. Extra left bits in both AndData and\r
+  OrData are stripped.\r
+\r
+  If any reserved bits in Address are set, then ASSERT().\r
+  If StartBit is greater than 31, then ASSERT().\r
+  If EndBit is greater than 31, then ASSERT().\r
+  If EndBit is less than StartBit, then ASSERT().\r
+\r
+  @param  Address   PCI configuration register to write.\r
+  @param  StartBit  The ordinal of the least significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  EndBit    The ordinal of the most significant bit in the bit field.\r
+                    Range 0..31.\r
+  @param  AndData   The value to AND with the PCI configuration register.\r
+  @param  OrData    The value to OR with the result of the AND operation.\r
+\r
+  @return The value written back to the PCI configuration register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PciSegmentBitFieldAndThenOr32 (\r
+  IN      UINT64                    Address,\r
+  IN      UINTN                     StartBit,\r
+  IN      UINTN                     EndBit,\r
+  IN      UINT32                    AndData,\r
+  IN      UINT32                    OrData\r
+  )\r
+{\r
+  return PciSegmentWrite32 (\r
+           Address,\r
+           BitFieldAndThenOr32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData, OrData)\r
+           );\r
+}\r
+\r
+/**\r
+  Reads a range of PCI configuration registers into a caller supplied buffer.\r
+\r
+  Reads the range of PCI configuration registers specified by StartAddress and\r
+  Size into the buffer specified by Buffer. This function only allows the PCI\r
+  configuration registers from a single PCI function to be read. Size is\r
+  returned. When possible 32-bit PCI configuration read cycles are used to read\r
+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit\r
+  and 16-bit PCI configuration read cycles may be used at the beginning and the\r
+  end of the range.\r
+\r
+  If StartAddress > 0x0FFFFFFF, then ASSERT().\r
+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
+  If Size > 0 and Buffer is NULL, then ASSERT().\r
+\r
+  @param  StartAddress  Starting Address that encodes the PCI Segment, Bus, Device,\r
+                        Function and Register.\r
+  @param  Size          Size in bytes of the transfer.\r
+  @param  Buffer        Pointer to a buffer receiving the data read.\r
+\r
+  @return Size\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+PciSegmentReadBuffer (\r
+  IN      UINT64                    StartAddress,\r
+  IN      UINTN                     Size,\r
+  OUT     VOID                      *Buffer\r
+  )\r
+{\r
+  UINTN                             ReturnValue;\r
+\r
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);\r
+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
+\r
+  if (Size == 0) {\r
+    return Size;\r
+  }\r
+\r
+  ASSERT (Buffer != NULL);\r
+\r
+  //\r
+  // Save Size for return\r
+  //\r
+  ReturnValue = Size;\r
+\r
+  if ((StartAddress & 1) != 0) {\r
+    //\r
+    // Read a byte if StartAddress is byte aligned\r
+    //\r
+    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);\r
+    StartAddress += sizeof (UINT8);\r
+    Size -= sizeof (UINT8);\r
+    Buffer = (UINT8*)Buffer + 1;\r
+  }\r
+\r
+  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {\r
+    //\r
+    // Read a word if StartAddress is word aligned\r
+    //\r
+    *(volatile UINT16 *)Buffer = PciSegmentRead16 (StartAddress);\r
+    StartAddress += sizeof (UINT16);\r
+    Size -= sizeof (UINT16);\r
+    Buffer = (UINT16*)Buffer + 1;\r
+  }\r
+\r
+  while (Size >= sizeof (UINT32)) {\r
+    //\r
+    // Read as many double words as possible\r
+    //\r
+    *(volatile UINT32 *)Buffer = PciSegmentRead32 (StartAddress);\r
+    StartAddress += sizeof (UINT32);\r
+    Size -= sizeof (UINT32);\r
+    Buffer = (UINT32*)Buffer + 1;\r
+  }\r
+\r
+  if (Size >= sizeof (UINT16)) {\r
+    //\r
+    // Read the last remaining word if exist\r
+    //\r
+    *(volatile UINT16 *)Buffer = PciSegmentRead16 (StartAddress);\r
+    StartAddress += sizeof (UINT16);\r
+    Size -= sizeof (UINT16);\r
+    Buffer = (UINT16*)Buffer + 1;\r
+  }\r
+\r
+  if (Size >= sizeof (UINT8)) {\r
+    //\r
+    // Read the last remaining byte if exist\r
+    //\r
+    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);\r
+  }\r
+\r
+  return ReturnValue;\r
+}\r
+\r
+/**\r
+  Copies the data in a caller supplied buffer to a specified range of PCI\r
+  configuration space.\r
+\r
+  Writes the range of PCI configuration registers specified by StartAddress and\r
+  Size from the buffer specified by Buffer. This function only allows the PCI\r
+  configuration registers from a single PCI function to be written. Size is\r
+  returned. When possible 32-bit PCI configuration write cycles are used to\r
+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,\r
+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning\r
+  and the end of the range.\r
+\r
+  If StartAddress > 0x0FFFFFFF, then ASSERT().\r
+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
+  If Size > 0 and Buffer is NULL, then ASSERT().\r
+\r
+  @param  StartAddress  Starting Address that encodes the PCI Segment, Bus, Device,\r
+                        Function and Register.\r
+  @param  Size          Size in bytes of the transfer.\r
+  @param  Buffer        Pointer to a buffer containing the data to write.\r
+\r
+  @return Size\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+PciSegmentWriteBuffer (\r
+  IN      UINT64                    StartAddress,\r
+  IN      UINTN                     Size,\r
+  IN      VOID                      *Buffer\r
+  )\r
+{\r
+  UINTN                             ReturnValue;\r
+\r
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);\r
+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
+\r
+  if (Size == 0) {\r
+    return 0;\r
+  }\r
+\r
+  ASSERT (Buffer != NULL);\r
+\r
+  //\r
+  // Save Size for return\r
+  //\r
+  ReturnValue = Size;\r
+\r
+  if ((StartAddress & 1) != 0) {\r
+    //\r
+    // Write a byte if StartAddress is byte aligned\r
+    //\r
+    PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);\r
+    StartAddress += sizeof (UINT8);\r
+    Size -= sizeof (UINT8);\r
+    Buffer = (UINT8*)Buffer + 1;\r
+  }\r
+\r
+  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {\r
+    //\r
+    // Write a word if StartAddress is word aligned\r
+    //\r
+    PciSegmentWrite16 (StartAddress, *(UINT16*)Buffer);\r
+    StartAddress += sizeof (UINT16);\r
+    Size -= sizeof (UINT16);\r
+    Buffer = (UINT16*)Buffer + 1;\r
+  }\r
+\r
+  while (Size >= sizeof (UINT32)) {\r
+    //\r
+    // Write as many double words as possible\r
+    //\r
+    PciSegmentWrite32 (StartAddress, *(UINT32*)Buffer);\r
+    StartAddress += sizeof (UINT32);\r
+    Size -= sizeof (UINT32);\r
+    Buffer = (UINT32*)Buffer + 1;\r
+  }\r
+\r
+  if (Size >= sizeof (UINT16)) {\r
+    //\r
+    // Write the last remaining word if exist\r
+    //\r
+    PciSegmentWrite16 (StartAddress, *(UINT16*)Buffer);\r
+    StartAddress += sizeof (UINT16);\r
+    Size -= sizeof (UINT16);\r
+    Buffer = (UINT16*)Buffer + 1;\r
+  }\r
+\r
+  if (Size >= sizeof (UINT8)) {\r
+    //\r
+    // Write the last remaining byte if exist\r
+    //\r
+    PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);\r
+  }\r
+\r
+  return ReturnValue;\r
+}\r
diff --git a/MdePkg/Library/DxeRuntimeExtendedSalLib/DxeRuntimeExtendedSalLib.inf b/MdePkg/Library/DxeRuntimeExtendedSalLib/DxeRuntimeExtendedSalLib.inf
new file mode 100644 (file)
index 0000000..a53d9f6
--- /dev/null
@@ -0,0 +1,50 @@
+## @file\r
+#  This library implements the Extended SAL Library Class for use in boot services and runtime.\r
+#\r
+#  Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  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
+#  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
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DxeRuntimeExtendedSalLib\r
+  FILE_GUID                      = AE66715B-75F5-4423-8FAD-A4AFB3C53ACF\r
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = ExtendedSalLib|DXE_RUNTIME_DRIVER DXE_SAL_DRIVER \r
+  CONSTRUCTOR                    = DxeRuntimeExtendedSalLibConstruct\r
+  DESTRUCTOR                     = DxeRuntimeExtendedSalLibDeconstruct\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IPF\r
+#\r
+\r
+[Sources.IPF]\r
+  ExtendedSalLib.c\r
+  Ipf/AsmExtendedSalLib.s\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiBootServicesTableLib\r
+  UefiRuntimeServicesTableLib\r
+  DebugLib\r
+\r
+[Protocols]\r
+  gEfiExtendedSalBootServiceProtocolGuid        # PROTOCOL ALWAYS_CONSUMED\r
+\r
+[Guids]\r
+  gEfiEventVirtualAddressChangeGuid\r
+\r
+[Depex]\r
+  gEfiExtendedSalBootServiceProtocolGuid\r
diff --git a/MdePkg/Library/DxeRuntimeExtendedSalLib/ExtendedSalLib.c b/MdePkg/Library/DxeRuntimeExtendedSalLib/ExtendedSalLib.c
new file mode 100644 (file)
index 0000000..1a599e6
--- /dev/null
@@ -0,0 +1,1122 @@
+/** @file\r
+  This library implements the Extended SAL Library Class for use in boot services and runtime.\r
+\r
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  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 <PiDxe.h>\r
+\r
+#include <Protocol/ExtendedSalBootService.h>\r
+#include <Protocol/ExtendedSalServiceClasses.h>\r
+#include <Guid/EventGroup.h>\r
+\r
+#include <Library/ExtendedSalLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/UefiRuntimeLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+/**\r
+  Stores the virtual plabel of ESAL entrypoint.\r
+\r
+  This assembly function stores the virtual plabel of ESAL entrypoint\r
+  where GetEsalEntryPoint() can easily retrieve.\r
+\r
+  @param  EntryPoint  Virtual address of ESAL entrypoint\r
+  @param  Gp          Virtual GP of ESAL entrypoint\r
+\r
+  @return r8 = EFI_SAL_SUCCESS\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+SetEsalVirtualEntryPoint (\r
+  IN  UINT64  EntryPoint,\r
+  IN  UINT64  Gp\r
+  );\r
+\r
+/**\r
+  Stores the physical plabel of ESAL entrypoint.\r
+\r
+  This assembly function stores the physical plabel of ESAL entrypoint\r
+  where GetEsalEntryPoint() can easily retrieve.\r
+\r
+  @param  EntryPoint  Physical address of ESAL entrypoint\r
+  @param  Gp          Physical GP of ESAL entrypoint\r
+\r
+  @return r8 = EFI_SAL_SUCCESS\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+SetEsalPhysicalEntryPoint (\r
+  IN  UINT64  EntryPoint,\r
+  IN  UINT64  Gp\r
+  );\r
+\r
+/**\r
+  Retrieves plabel of ESAL entrypoint.\r
+\r
+  This function retrives plabel of ESAL entrypoint stored by\r
+  SetEsalPhysicalEntryPoint().\r
+\r
+  @return r8  = EFI_SAL_SUCCESS\r
+          r9  = Physical Plabel\r
+          r10 = Virtual Plabel\r
+          r11 = PSR\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+GetEsalEntryPoint (\r
+  VOID\r
+  );\r
+\r
+EXTENDED_SAL_BOOT_SERVICE_PROTOCOL  *mEsalBootService = NULL;\r
+EFI_PLABEL                          mPlabel;\r
+EFI_EVENT                           mEfiVirtualNotifyEvent;\r
+\r
+/**\r
+  Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE to set virtual plabel of\r
+  ESAL entrypoint.\r
+\r
+  This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.\r
+  It converts physical plabel of ESAL entrypoint to virtual plabel and stores it where\r
+  GetEsalEntryPoint() can easily retrieve.\r
+\r
+  @param  Event        Event whose notification function is being invoked.\r
+  @param  Context      Pointer to the notification function's context\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ExtendedSalVirtualNotifyEvent (\r
+  IN EFI_EVENT        Event,\r
+  IN VOID             *Context\r
+  )\r
+{\r
+  UINT64  PhysicalEntryPoint;\r
+\r
+  PhysicalEntryPoint = mPlabel.EntryPoint;\r
+\r
+  gRT->ConvertPointer (0x0, (VOID **) &mPlabel.EntryPoint);\r
+\r
+  mPlabel.GP += mPlabel.EntryPoint - PhysicalEntryPoint;\r
+\r
+  SetEsalVirtualEntryPoint (mPlabel.EntryPoint, mPlabel.GP);\r
+}\r
+\r
+/**\r
+  Gets Extended SAL Boot Service Protocol, and initializes physical plabel of\r
+  ESAL entrypoint.\r
+\r
+  This function first locates Extended SAL Boot Service Protocol and caches it in global variable.\r
+  Then it initializes the physical plable of ESAL entrypoint, and stores\r
+  it where GetEsalEntryPoint() can easily retrieve.\r
+\r
+  @retval  EFI_SUCCESS  Plable of ESAL entrypoint successfully stored.\r
+\r
+**/\r
+EFI_STATUS\r
+DxeSalLibInitialize (\r
+  VOID\r
+  )\r
+{\r
+  EFI_PLABEL  *Plabel;\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // The protocol contains a function pointer, which is an indirect procedure call.\r
+  // An indirect procedure call goes through a plabel, and pointer to a function is\r
+  // a pointer to a plabel. To implement indirect procedure calls that can work in\r
+  // both physical and virtual mode, two plabels are required (one physical and one\r
+  // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it\r
+  // away. We cache it in a module global, so we can register the vitrual version.\r
+  //\r
+  Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, (VOID **) &mEsalBootService);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Plabel              = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;\r
+  mPlabel.EntryPoint  = Plabel->EntryPoint;\r
+  mPlabel.GP          = Plabel->GP;\r
+  //\r
+  // Stores the physical plabel of ESAL entrypoint where GetEsalEntryPoint() can easily retrieve.\r
+  //\r
+  SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Constructor function to initializes physical plabel of ESAL entrypoint and register an event\r
+  for initialization of virtual plabel of ESAL entrypoint.\r
+  \r
+  This is the library constructor function to call a function to initialize physical plabel of ESAL entrypoint\r
+  and to register notification function for \r
+  EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, which sets virtual plabel of ESAL entrypoint.\r
+\r
+  @param  ImageHandle   The firmware allocated handle for the EFI image.\r
+  @param  SystemTable   A pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS   Notification function successfully registered.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeRuntimeExtendedSalLibConstruct (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Register notify function for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE\r
+  //\r
+  ASSERT (gBS != NULL);\r
+\r
+  DxeSalLibInitialize ();\r
+\r
+  Status = gBS->CreateEventEx (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_NOTIFY,\r
+                  ExtendedSalVirtualNotifyEvent,\r
+                  NULL,\r
+                  &gEfiEventVirtualAddressChangeGuid,\r
+                  &mEfiVirtualNotifyEvent\r
+                  );\r
+\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Destructor function to close the event created by the library constructor \r
+  \r
+  This is the library destructor function to close the event with type of \r
+  EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, which is created by the library constructor.\r
+\r
+  @param  ImageHandle   The firmware allocated handle for the EFI image.\r
+  @param  SystemTable   A pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS   Event successfully closed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeRuntimeExtendedSalLibDeconstruct (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Close SetVirtualAddressMap () notify function\r
+  //\r
+  ASSERT (gBS != NULL);\r
+  Status = gBS->CloseEvent (mEfiVirtualNotifyEvent);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Registers function of ESAL class and it's associated global.\r
+  \r
+  This function registers function of ESAL class, together with its associated global.\r
+  It is worker function for RegisterEsalClass().\r
+  It is only for boot time.\r
+\r
+  @param  FunctionId     ID of function to register\r
+  @param  ClassGuidLo    GUID of ESAL class, lower 64-bits\r
+  @param  ClassGuidHi    GUID of ESAL class, upper 64-bits\r
+  @param  Function       Function to register with ClassGuid/FunctionId pair\r
+  @param  ModuleGlobal   Module global for the function.\r
+\r
+  @return Status returned by RegisterExtendedSalProc() of Extended SAL Boot Service Protocol\r
+\r
+**/\r
+EFI_STATUS\r
+RegisterEsalFunction (\r
+  IN  UINT64                                    FunctionId,\r
+  IN  UINT64                                    ClassGuidLo,\r
+  IN  UINT64                                    ClassGuidHi,\r
+  IN  SAL_INTERNAL_EXTENDED_SAL_PROC            Function,\r
+  IN  VOID                                      *ModuleGlobal\r
+  )\r
+{\r
+  return mEsalBootService->RegisterExtendedSalProc (\r
+                             mEsalBootService,\r
+                             ClassGuidLo,\r
+                             ClassGuidHi,\r
+                             FunctionId,\r
+                             Function,\r
+                             ModuleGlobal\r
+                             );\r
+}\r
+\r
+/**\r
+  Registers ESAL Class and it's associated global.\r
+  \r
+  This function registers one or more Extended SAL services in a given\r
+  class along with the associated global context.\r
+  This function is only available prior to ExitBootServices().\r
+\r
+  @param  ClassGuidLo          GUID of function class, lower 64-bits\r
+  @param  ClassGuidHi          GUID of function class, upper 64-bits\r
+  @param  ModuleGlobal         Module global for the class.\r
+  @param  ...                  List of Function/FunctionId pairs, ended by NULL\r
+\r
+  @retval EFI_SUCCESS          The Extended SAL services were registered.\r
+  @retval EFI_UNSUPPORTED      This function was called after ExitBootServices().\r
+  @retval EFI_OUT_OF_RESOURCES There are not enough resources available to register one or more of the specified services.\r
+  @retval Other                ClassGuid could not be installed onto a new handle.  \r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RegisterEsalClass (\r
+  IN  CONST UINT64    ClassGuidLo,\r
+  IN  CONST UINT64    ClassGuidHi,\r
+  IN  VOID            *ModuleGlobal,  OPTIONAL\r
+  ...\r
+  )\r
+{\r
+  VA_LIST                         Args;\r
+  EFI_STATUS                      Status;\r
+  SAL_INTERNAL_EXTENDED_SAL_PROC  Function;\r
+  UINT64                          FunctionId;\r
+  EFI_HANDLE                      NewHandle;\r
+  EFI_GUID                        ClassGuid;\r
+\r
+  VA_START (Args, ModuleGlobal);\r
+\r
+  //\r
+  // Register all functions of the class to register.\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  while (!EFI_ERROR (Status)) {\r
+    Function = (SAL_INTERNAL_EXTENDED_SAL_PROC) VA_ARG (Args, SAL_INTERNAL_EXTENDED_SAL_PROC);\r
+    //\r
+    // NULL serves as the end mark of function list\r
+    //\r
+    if (Function == NULL) {\r
+      break;\r
+    }\r
+\r
+    FunctionId  = VA_ARG (Args, UINT64);\r
+\r
+    Status      = RegisterEsalFunction (FunctionId, ClassGuidLo, ClassGuidHi, Function, ModuleGlobal);\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  NewHandle = NULL;\r
+  *((UINT64 *)(&ClassGuid) + 0) = ClassGuidLo;\r
+  *((UINT64 *)(&ClassGuid) + 1) = ClassGuidHi;\r
+  return gBS->InstallProtocolInterface (\r
+                &NewHandle,\r
+                &ClassGuid,\r
+                EFI_NATIVE_INTERFACE,\r
+                NULL\r
+                );\r
+}\r
+\r
+/**\r
+  Calls an Extended SAL Class service that was previously registered with RegisterEsalClass().\r
+  \r
+  This function gets the entrypoint of Extended SAL, and calls an Extended SAL Class service\r
+  that was previously registered with RegisterEsalClass() through this entrypoint.\r
+\r
+  @param  ClassGuidLo     GUID of function, lower 64-bits\r
+  @param  ClassGuidHi     GUID of function, upper 64-bits\r
+  @param  FunctionId      Function in ClassGuid to call\r
+  @param  Arg2            Argument 2 ClassGuid/FunctionId defined\r
+  @param  Arg3            Argument 3 ClassGuid/FunctionId defined\r
+  @param  Arg4            Argument 4 ClassGuid/FunctionId defined\r
+  @param  Arg5            Argument 5 ClassGuid/FunctionId defined\r
+  @param  Arg6            Argument 6 ClassGuid/FunctionId defined\r
+  @param  Arg7            Argument 7 ClassGuid/FunctionId defined\r
+  @param  Arg8            Argument 8 ClassGuid/FunctionId defined\r
+  \r
+  @retval EFI_SAL_SUCCESS ESAL procedure successfully called.\r
+  @retval EFI_SAL_ERROR   The address of ExtendedSalProc() can not be correctly\r
+                          initialized.\r
+  @retval Other           Status returned from ExtendedSalProc() service of\r
+                          EXTENDED_SAL_BOOT_SERVICE_PROTOCOL.  \r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalCall (\r
+  IN  UINT64    ClassGuidLo,\r
+  IN  UINT64    ClassGuidHi,\r
+  IN  UINT64    FunctionId,\r
+  IN  UINT64    Arg2,\r
+  IN  UINT64    Arg3,\r
+  IN  UINT64    Arg4,\r
+  IN  UINT64    Arg5,\r
+  IN  UINT64    Arg6,\r
+  IN  UINT64    Arg7,\r
+  IN  UINT64    Arg8\r
+  )\r
+{\r
+  SAL_RETURN_REGS       ReturnReg;\r
+  EXTENDED_SAL_PROC     EsalProc;\r
+\r
+  //\r
+  // Get the entrypoint of Extended SAL\r
+  //\r
+  ReturnReg = GetEsalEntryPoint ();\r
+  if (*(UINT64 *)ReturnReg.r9 == 0 && *(UINT64 *)(ReturnReg.r9 + 8) == 0) {\r
+    //\r
+    // The ESAL Entry Point could not be initialized\r
+    //\r
+    ReturnReg.Status = EFI_SAL_ERROR;\r
+    return ReturnReg;\r
+  }\r
+\r
+  //\r
+  // Test PSR.it which is BIT36\r
+  //\r
+  if ((ReturnReg.r11 & BIT36) != 0) {\r
+    //\r
+    // Virtual mode plabel to entry point\r
+    //\r
+    EsalProc = (EXTENDED_SAL_PROC) ReturnReg.r10;\r
+  } else {\r
+    //\r
+    // Physical mode plabel to entry point\r
+    //\r
+    EsalProc = (EXTENDED_SAL_PROC) ReturnReg.r9;\r
+  }\r
+\r
+  return EsalProc (\r
+           ClassGuidLo,\r
+           ClassGuidHi,\r
+           FunctionId,\r
+           Arg2,\r
+           Arg3,\r
+           Arg4,\r
+           Arg5,\r
+           Arg6,\r
+           Arg7,\r
+           Arg8\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalStallFunctionId service of Extended SAL Stall Services Class.\r
+  \r
+  This function is a wrapper for the EsalStallFunctionId service of Extended SAL\r
+  Stall Services Class. See EsalStallFunctionId of Extended SAL Specification.\r
+\r
+  @param  Microseconds         The number of microseconds to delay.\r
+\r
+  @retval EFI_SAL_SUCCESS               Call completed without error.\r
+  @retval EFI_SAL_INVALID_ARGUMENT      Invalid argument.\r
+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR Virtual address not registered\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalStall (\r
+  IN UINTN  Microseconds\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_LO, \r
+           EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_HI, \r
+           StallFunctionId, \r
+           Microseconds, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalSetNewPalEntryFunctionId service of Extended SAL PAL Services Services Class.\r
+  \r
+  This function is a wrapper for the EsalSetNewPalEntryFunctionId service of Extended SAL\r
+  PAL Services Services Class. See EsalSetNewPalEntryFunctionId of Extended SAL Specification.\r
+\r
+  @param  PhysicalAddress        If TRUE, then PalEntryPoint is a physical address.\r
+                                 If FALSE, then PalEntryPoint is a virtual address.\r
+  @param  PalEntryPoint          The PAL Entry Point being set.\r
+\r
+  @retval EFI_SAL_SUCCESS                The PAL Entry Point was set.\r
+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR  This function was called in virtual mode before\r
+                                         virtual mappings for the specified Extended SAL\r
+                                         Procedure are available.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalSetNewPalEntry (\r
+  IN BOOLEAN  PhysicalAddress,\r
+  IN UINT64   PalEntryPoint\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO, \r
+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,\r
+           SetNewPalEntryFunctionId, \r
+           PhysicalAddress, \r
+           PalEntryPoint, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetNewPalEntryFunctionId service of Extended SAL PAL Services Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetNewPalEntryFunctionId service of Extended SAL\r
+  PAL Services Services Class. See EsalGetNewPalEntryFunctionId of Extended SAL Specification.\r
+\r
+  @param  PhysicalAddress        If TRUE, then PalEntryPoint is a physical address.\r
+                                 If FALSE, then PalEntryPoint is a virtual address.\r
+\r
+  @retval EFI_SAL_SUCCESS                The PAL Entry Point was retrieved and returned in\r
+                                         SAL_RETURN_REGS.r9.\r
+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR  This function was called in virtual mode before\r
+                                         virtual mappings for the specified Extended SAL\r
+                                         Procedure are available.\r
+  @return r9                             PAL entry point retrieved.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetNewPalEntry (\r
+  IN BOOLEAN  PhysicalAddress\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,\r
+           GetNewPalEntryFunctionId, \r
+           PhysicalAddress, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetStateBufferFunctionId service of Extended SAL MCA Log Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetStateBufferFunctionId service of Extended SAL\r
+  MCA Log Services Class. See EsalGetStateBufferFunctionId of Extended SAL Specification.\r
+\r
+  @param  McaType         See type parameter of SAL Procedure SAL_GET_STATE_INFO.\r
+  @param  McaBuffer             A pointer to the base address of the returned buffer.\r
+                                Copied from SAL_RETURN_REGS.r9.\r
+  @param  BufferSize            A pointer to the size, in bytes, of the returned buffer.\r
+                                Copied from SAL_RETURN_REGS.r10.\r
+\r
+  @retval EFI_SAL_SUCCESS       The memory buffer to store error records was returned in r9 and r10.\r
+  @retval EFI_OUT_OF_RESOURCES  A memory buffer for string error records in not available\r
+  @return r9                    Base address of the returned buffer\r
+  @return r10                   Size of the returned buffer in bytes\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetStateBuffer (\r
+  IN  UINT64  McaType,\r
+  OUT UINT8   **McaBuffer,\r
+  OUT UINTN   *BufferSize\r
+  )\r
+{\r
+  SAL_RETURN_REGS Regs;\r
+\r
+  Regs = EsalCall (\r
+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalGetStateBufferFunctionId, \r
+           McaType, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+\r
+  *McaBuffer  = (UINT8 *) Regs.r9;\r
+  *BufferSize = Regs.r10;\r
+\r
+  return Regs;\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalSaveStateBufferFunctionId service of Extended SAL MCA Log Services Class.\r
+  \r
+  This function is a wrapper for the EsalSaveStateBufferFunctionId service of Extended SAL\r
+  MCA Log Services Class. See EsalSaveStateBufferFunctionId of Extended SAL Specification.\r
+  \r
+  @param  McaType         See type parameter of SAL Procedure SAL_GET_STATE_INFO.\r
+\r
+  @retval EFI_SUCCESS  The memory buffer containing the error record was written to nonvolatile storage.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalSaveStateBuffer (\r
+  IN  UINT64  McaType\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalSaveStateBufferFunctionId, \r
+           McaType, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetVectorsFunctionId service of Extended SAL Base Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetVectorsFunctionId service of Extended SAL\r
+  Base Services Class. See EsalGetVectorsFunctionId of Extended SAL Specification.\r
+\r
+  @param  VectorType         The vector type to retrieve.\r
+                             0 - MCA, 1 - BSP INIT, 2 - BOOT_RENDEZ, 3 - AP INIT.\r
+\r
+  @retval EFI_SAL_SUCCESS          Call completed without error.\r
+  @retval EFI_SAL_INVALID_ARGUMENT Invalid argument.\r
+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered\r
+                                   with the SAL Procedure SAL_SET_VECTORS.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetVectors (\r
+  IN  UINT64  VectorType\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalGetVectorsFunctionId, \r
+           VectorType, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalMcGetParamsFunctionId service of Extended SAL Base Services Class.\r
+  \r
+  This function is a wrapper for the EsalMcGetParamsFunctionId service of Extended SAL\r
+  Base Services Class. See EsalMcGetParamsFunctionId of Extended SAL Specification.\r
+\r
+  @param  ParamInfoType         The parameter type to retrieve.\r
+                                1 - rendezvous interrupt\r
+                                2 - wake up\r
+                                3 - Corrected Platform Error Vector.\r
+\r
+  @retval EFI_SAL_SUCCESS          Call completed without error.\r
+  @retval EFI_SAL_INVALID_ARGUMENT Invalid argument.\r
+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered\r
+                                   with the SAL Procedure SAL_MC_SET_PARAMS.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalMcGetParams (\r
+  IN  UINT64  ParamInfoType\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalMcGetParamsFunctionId, \r
+           ParamInfoType, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalMcGetParamsFunctionId service of Extended SAL Base Services Class.\r
+  \r
+  This function is a wrapper for the EsalMcGetParamsFunctionId service of Extended SAL\r
+  Base Services Class. See EsalMcGetParamsFunctionId of Extended SAL Specification.\r
+  \r
+  @retval EFI_SAL_SUCCESS          Call completed without error.\r
+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered\r
+                                   with the SAL Procedure SAL_MC_SET_PARAMS.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalMcGetMcParams (\r
+  VOID\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalMcGetMcParamsFunctionId, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetMcCheckinFlagsFunctionId service of Extended SAL Base Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetMcCheckinFlagsFunctionId service of Extended SAL\r
+  Base Services Class. See EsalGetMcCheckinFlagsFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuIndex         The index of the CPU of set of enabled CPUs to check.\r
+\r
+  @retval EFI_SAL_SUCCESS  The checkin status of the requested CPU was returned.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetMcCheckinFlags (\r
+  IN  UINT64  CpuIndex\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalGetMcCheckinFlagsFunctionId, \r
+           CpuIndex, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalAddCpuDataFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalAddCpuDataFunctionId service of Extended SAL\r
+  MP Services Class. See EsalAddCpuDataFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId         The Global ID for the CPU being added.\r
+  @param  Enabled             The enable flag for the CPU being added.\r
+                              TRUE means the CPU is enabled.\r
+                              FALSE means the CPU is disabled.\r
+  @param  PalCompatibility    The PAL Compatibility value for the CPU being added.\r
+\r
+  @retval EFI_SAL_SUCCESS             The CPU was added to the database.\r
+  @retval EFI_SAL_NOT_ENOUGH_SCRATCH  There are not enough resource available to add the CPU.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalAddCpuData (\r
+  IN UINT64   CpuGlobalId,\r
+  IN BOOLEAN  Enabled,\r
+  IN UINT64   PalCompatibility\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           AddCpuDataFunctionId, \r
+           CpuGlobalId, \r
+           Enabled, \r
+           PalCompatibility, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalRemoveCpuDataFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalRemoveCpuDataFunctionId service of Extended SAL\r
+  MP Services Class. See EsalRemoveCpuDataFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId         The Global ID for the CPU being removed.\r
+\r
+  @retval EFI_SAL_SUCCESS         The CPU was removed from the database.\r
+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalRemoveCpuData (\r
+  IN UINT64  CpuGlobalId\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           RemoveCpuDataFunctionId, \r
+           CpuGlobalId, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalModifyCpuDataFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalModifyCpuDataFunctionId service of Extended SAL\r
+  MP Services Class. See EsalModifyCpuDataFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId         The Global ID for the CPU being modified.\r
+  @param  Enabled             The enable flag for the CPU being modified.\r
+                              TRUE means the CPU is enabled.\r
+                              FALSE means the CPU is disabled.\r
+  @param  PalCompatibility    The PAL Compatibility value for the CPU being modified.\r
+\r
+  @retval EFI_SAL_SUCCESS         The CPU database was updated.\r
+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalModifyCpuData (\r
+  IN UINT64   CpuGlobalId,\r
+  IN BOOLEAN  Enabled,\r
+  IN UINT64   PalCompatibility\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           ModifyCpuDataFunctionId, \r
+           CpuGlobalId, \r
+           Enabled, \r
+           PalCompatibility, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetCpuDataByIdFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetCpuDataByIdFunctionId service of Extended SAL\r
+  MP Services Class. See EsalGetCpuDataByIdFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId         The Global ID for the CPU being looked up.\r
+  @param  IndexByEnabledCpu   If TRUE, then the index of set of enabled CPUs of database is returned.\r
+                              If FALSE, then the index of set of all CPUs of database is returned.\r
+\r
+  @retval EFI_SAL_SUCCESS         The information on the specified CPU was returned.\r
+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetCpuDataById (\r
+  IN UINT64   CpuGlobalId,\r
+  IN BOOLEAN  IndexByEnabledCpu\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           GetCpuDataByIDFunctionId, \r
+           CpuGlobalId, \r
+           IndexByEnabledCpu, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetCpuDataByIndexFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetCpuDataByIndexFunctionId service of Extended SAL\r
+  MP Services Class. See EsalGetCpuDataByIndexFunctionId of Extended SAL Specification.\r
+\r
+  @param  Index               The Global ID for the CPU being modified.\r
+  @param  IndexByEnabledCpu   If TRUE, then the index of set of enabled CPUs of database is returned.\r
+                              If FALSE, then the index of set of all CPUs of database is returned.\r
+\r
+  @retval EFI_SAL_SUCCESS         The information on the specified CPU was returned.\r
+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetCpuDataByIndex (\r
+  IN UINT64   Index,\r
+  IN BOOLEAN  IndexByEnabledCpu\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           GetCpuDataByIndexFunctionId, \r
+           Index, \r
+           IndexByEnabledCpu, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalWhoAmIFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalWhoAmIFunctionId service of Extended SAL\r
+  MP Services Class. See EsalWhoAmIFunctionId of Extended SAL Specification.\r
+\r
+  @param  IndexByEnabledCpu   If TRUE, then the index of set of enabled CPUs of database is returned.\r
+                              If FALSE, then the index of set of all CPUs of database is returned.\r
+\r
+  @retval EFI_SAL_SUCCESS         The Global ID for the calling CPU was returned.\r
+  @retval EFI_SAL_NO_INFORMATION  The calling CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalWhoAmI (\r
+  IN BOOLEAN  IndexByEnabledCpu\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           CurrentProcInfoFunctionId, \r
+           IndexByEnabledCpu, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalNumProcessors service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalNumProcessors service of Extended SAL\r
+  MP Services Class. See EsalNumProcessors of Extended SAL Specification.\r
+\r
+  @retval EFI_SAL_SUCCESS    The information on the number of CPUs in the platform\r
+                             was returned.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalNumProcessors (\r
+  VOID\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           NumProcessorsFunctionId, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalSetMinStateFnctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalSetMinStateFnctionId service of Extended SAL\r
+  MP Services Class. See EsalSetMinStateFnctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId       The Global ID for the CPU whose MINSTATE pointer is being set.\r
+  @param  MinStatePointer          The physical address of the MINSTATE buffer for the CPU\r
+                                   specified by CpuGlobalId.\r
+\r
+  @retval EFI_SAL_SUCCESS          The MINSTATE pointer was set for the specified CPU.\r
+  @retval EFI_SAL_NO_INFORMATION   The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalSetMinState (\r
+  IN UINT64                CpuGlobalId,\r
+  IN EFI_PHYSICAL_ADDRESS  MinStatePointer\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           SetMinStateFunctionId, \r
+           CpuGlobalId, \r
+           MinStatePointer, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetMinStateFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetMinStateFunctionId service of Extended SAL\r
+  MP Services Class. See EsalGetMinStateFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId   The Global ID for the CPU whose MINSTATE pointer is being retrieved.\r
+\r
+  @retval EFI_SAL_SUCCESS        The MINSTATE pointer for the specified CPU was retrieved.\r
+  @retval EFI_SAL_NO_INFORMATION The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetMinState (\r
+  IN UINT64  CpuGlobalId\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           GetMinStateFunctionId, \r
+           CpuGlobalId, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalMcsGetStateInfoFunctionId service of Extended SAL MCA Services Class.\r
+  \r
+  This function is a wrapper for the EsalMcsGetStateInfoFunctionId service of Extended SAL\r
+  MCA Services Class. See EsalMcsGetStateInfoFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId               The Global ID for the CPU whose MCA state buffer is being retrieved.\r
+  @param  StateBufferPointer        A pointer to the returned MCA state buffer.\r
+  @param  RequiredStateBufferSize   A pointer to the size, in bytes, of the returned MCA state buffer.\r
+\r
+  @retval EFI_SUCCESS               MINSTATE successfully got and size calculated.\r
+  @retval EFI_SAL_NO_INFORMATION    Fail to get MINSTATE.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalMcaGetStateInfo (\r
+  IN  UINT64                CpuGlobalId,\r
+  OUT EFI_PHYSICAL_ADDRESS  *StateBufferPointer,\r
+  OUT UINT64                *RequiredStateBufferSize\r
+  )\r
+{\r
+  SAL_RETURN_REGS  Regs;\r
+\r
+  Regs = EsalCall (\r
+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_HI,\r
+           McaGetStateInfoFunctionId, \r
+           CpuGlobalId, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+\r
+  *StateBufferPointer      = (EFI_PHYSICAL_ADDRESS) Regs.r9;\r
+  *RequiredStateBufferSize = (UINT64) Regs.r10;\r
+\r
+  return Regs;\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalMcaRegisterCpuFunctionId service of Extended SAL MCA Services Class.\r
+  \r
+  This function is a wrapper for the EsalMcaRegisterCpuFunctionId service of Extended SAL\r
+  MCA Services Class. See EsalMcaRegisterCpuFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId          The Global ID for the CPU whose MCA state buffer is being set.\r
+  @param  StateBufferPointer   A pointer to the MCA state buffer.\r
+\r
+  @retval EFI_SAL_NO_INFORMATION   Cannot get the processor info with the CpuId\r
+  @retval EFI_SUCCESS              Save the processor's state info successfully\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalMcaRegisterCpu (\r
+  IN UINT64                CpuGlobalId,\r
+  IN EFI_PHYSICAL_ADDRESS  StateBufferPointer\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_HI,\r
+           McaRegisterCpuFunctionId, \r
+           CpuGlobalId, \r
+           StateBufferPointer, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
diff --git a/MdePkg/Library/DxeRuntimeExtendedSalLib/Ipf/AsmExtendedSalLib.s b/MdePkg/Library/DxeRuntimeExtendedSalLib/Ipf/AsmExtendedSalLib.s
new file mode 100644 (file)
index 0000000..ddabc76
--- /dev/null
@@ -0,0 +1,131 @@
+/// @file\r
+///  Assembly procedures to get and set ESAL entry point.\r
+///\r
+/// Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+/// 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
+.auto\r
+.text\r
+\r
+#include  "IpfMacro.i"\r
+\r
+//\r
+// Exports\r
+//\r
+ASM_GLOBAL GetEsalEntryPoint\r
+\r
+//-----------------------------------------------------------------------------\r
+//++\r
+// GetEsalEntryPoint\r
+//\r
+// Return Esal global and PSR register.\r
+//\r
+// On Entry :\r
+//\r
+//\r
+// Return Value:\r
+//        r8  = EFI_SAL_SUCCESS\r
+//        r9  = Physical Plabel\r
+//        r10 = Virtual Plabel\r
+//        r11 = psr\r
+// \r
+// As per static calling conventions. \r
+// \r
+//--\r
+//---------------------------------------------------------------------------\r
+PROCEDURE_ENTRY (GetEsalEntryPoint)\r
+\r
+      NESTED_SETUP (0,8,0,0)\r
+\r
+EsalCalcStart:\r
+      mov   r8  = ip;;\r
+      add   r8  = (EsalEntryPoint - EsalCalcStart), r8;;\r
+      mov   r9  = r8;;\r
+      add   r10 = 0x10, r8;;\r
+      mov   r11 = psr;;\r
+      mov   r8  = r0;;\r
+\r
+      NESTED_RETURN\r
+\r
+PROCEDURE_EXIT (GetEsalEntryPoint)\r
+\r
+//-----------------------------------------------------------------------------\r
+//++\r
+// SetEsalPhysicalEntryPoint\r
+//\r
+// Set the dispatcher entry point\r
+//\r
+// On Entry:\r
+//  in0 = Physical address of Esal Dispatcher\r
+//  in1 = Physical GP\r
+//\r
+// Return Value: \r
+//   r8 = EFI_SAL_SUCCESS\r
+// \r
+// As per static calling conventions. \r
+// \r
+//--\r
+//---------------------------------------------------------------------------\r
+PROCEDURE_ENTRY (SetEsalPhysicalEntryPoint)\r
+\r
+      NESTED_SETUP (2,8,0,0)\r
+\r
+EsalCalcStart1:\r
+      mov   r8   = ip;;\r
+      add   r8   = (EsalEntryPoint - EsalCalcStart1), r8;;\r
+      st8   [r8] = in0;;\r
+      add   r8   = 0x08, r8;;\r
+      st8   [r8] = in1;;\r
+      mov   r8   = r0;;\r
+\r
+      NESTED_RETURN\r
+\r
+PROCEDURE_EXIT (SetEsalPhysicalEntryPoint)\r
+\r
+//-----------------------------------------------------------------------------\r
+//++\r
+// SetEsalVirtualEntryPoint\r
+//\r
+// Register physical address of Esal globals.\r
+//\r
+// On Entry :\r
+//  in0 = Virtual address of Esal Dispatcher\r
+//  in1 = Virtual GP\r
+//\r
+// Return Value: \r
+//  r8 = EFI_SAL_ERROR\r
+// \r
+// As per static calling conventions. \r
+// \r
+//--\r
+//---------------------------------------------------------------------------\r
+PROCEDURE_ENTRY (SetEsalVirtualEntryPoint)\r
+\r
+      NESTED_SETUP (2,8,0,0)\r
+\r
+EsalCalcStart2:\r
+      mov   r8   = ip;;\r
+      add   r8   = (EsalEntryPoint - EsalCalcStart2), r8;;\r
+      add   r8   = 0x10, r8;;\r
+      st8   [r8] = in0;;\r
+      add   r8   = 0x08, r8;;\r
+      st8   [r8] = in1;;\r
+      mov   r8   = r0;;\r
+\r
+      NESTED_RETURN\r
+\r
+PROCEDURE_EXIT (SetEsalVirtualEntryPoint)\r
+\r
+.align 32\r
+EsalEntryPoint: \r
+    data8 0   // Physical Entry\r
+    data8 0   //         GP\r
+    data8 0   // Virtual Entry\r
+    data8 0   //         GP\r
diff --git a/MdePkg/Library/DxeSalLibEsal/DxeSalLibEsal.c b/MdePkg/Library/DxeSalLibEsal/DxeSalLibEsal.c
new file mode 100644 (file)
index 0000000..b013146
--- /dev/null
@@ -0,0 +1,279 @@
+/** @file\r
+  This library implements the SAL Library Class using Extended SAL functions\r
+\r
+  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  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 <PiDxe.h>\r
+\r
+#include <Protocol/ExtendedSalServiceClasses.h>\r
+\r
+#include <Library/SalLib.h>\r
+#include <Library/ExtendedSalLib.h>\r
+\r
+/**\r
+  Makes a SAL procedure call.\r
+  \r
+  This is a wrapper function to make a SAL procedure call.  \r
+  No parameter checking is performed on the 8 input parameters,\r
+  but there are some common rules that the caller should follow\r
+  when making a SAL call.  Any address passed to SAL as buffers\r
+  for return parameters must be 8-byte aligned.  Unaligned\r
+  addresses may cause undefined results.  For those parameters\r
+  defined as reserved or some fields defined as reserved must be\r
+  zero filled or the invalid argument return value may be returned\r
+  or undefined result may occur during the execution of the procedure.\r
+  This function is only available on IPF.\r
+\r
+  @param  Index       The SAL procedure Index number\r
+  @param  Arg2        The 2nd parameter for SAL procedure calls\r
+  @param  Arg3        The 3rd parameter for SAL procedure calls\r
+  @param  Arg4        The 4th parameter for SAL procedure calls\r
+  @param  Arg5        The 5th parameter for SAL procedure calls\r
+  @param  Arg6        The 6th parameter for SAL procedure calls\r
+  @param  Arg7        The 7th parameter for SAL procedure calls\r
+  @param  Arg8        The 8th parameter for SAL procedure calls\r
+\r
+  @return SAL returned registers.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+SalCall (\r
+  IN UINT64  Index,\r
+  IN UINT64  Arg2,\r
+  IN UINT64  Arg3,\r
+  IN UINT64  Arg4,\r
+  IN UINT64  Arg5,\r
+  IN UINT64  Arg6,\r
+  IN UINT64  Arg7,\r
+  IN UINT64  Arg8\r
+  )\r
+{\r
+  SAL_RETURN_REGS Regs;\r
+\r
+  switch (Index) {\r
+  case EFI_SAL_SET_VECTORS:\r
+    return EsalCall (\r
+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+             SalSetVectorsFunctionId, \r
+             Arg2, \r
+             Arg3, \r
+             Arg4, \r
+             Arg5, \r
+             Arg6, \r
+             Arg7, \r
+             Arg8\r
+             );\r
+    break;\r
+\r
+  case EFI_SAL_GET_STATE_INFO:\r
+    return EsalCall (\r
+             EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,\r
+             EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,\r
+             SalGetStateInfoFunctionId, \r
+             Arg2, \r
+             Arg3, \r
+             Arg4, \r
+             Arg5, \r
+             Arg6, \r
+             Arg7, \r
+             Arg8\r
+             );\r
+    break;\r
+\r
+  case EFI_SAL_GET_STATE_INFO_SIZE:\r
+    return EsalCall (\r
+             EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,\r
+             EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,\r
+             SalGetStateInfoSizeFunctionId, \r
+             Arg2, \r
+             Arg3, \r
+             Arg4, \r
+             Arg5, \r
+             Arg6, \r
+             Arg7, \r
+             Arg8\r
+             );\r
+    break;\r
+\r
+  case EFI_SAL_CLEAR_STATE_INFO:\r
+    return EsalCall (\r
+             EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,\r
+             EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,\r
+             SalClearStateInfoFunctionId, \r
+             Arg2, \r
+             Arg3, \r
+             Arg4, \r
+             Arg5, \r
+             Arg6, \r
+             Arg7, \r
+             Arg8\r
+             );\r
+    break;\r
+\r
+  case EFI_SAL_MC_RENDEZ:\r
+    return EsalCall (\r
+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+             SalMcRendezFunctionId, \r
+             Arg2, \r
+             Arg3, \r
+             Arg4, \r
+             Arg5, \r
+             Arg6, \r
+             Arg7, \r
+             Arg8\r
+             );\r
+   break;\r
+\r
+  case EFI_SAL_MC_SET_PARAMS:\r
+    return EsalCall (\r
+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+             SalMcSetParamsFunctionId, \r
+             Arg2, \r
+             Arg3, \r
+             Arg4, \r
+             Arg5, \r
+             Arg6, \r
+             Arg7, \r
+             Arg8\r
+             );\r
+    break;\r
+\r
+  case EFI_SAL_REGISTER_PHYSICAL_ADDR:\r
+    return EsalCall (\r
+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+             EsalRegisterPhysicalAddrFunctionId, \r
+             Arg2, \r
+             Arg3, \r
+             Arg4, \r
+             Arg5, \r
+             Arg6, \r
+             Arg7, \r
+             Arg8\r
+             );\r
+    break;\r
+\r
+  case EFI_SAL_CACHE_FLUSH:\r
+    return EsalCall (\r
+             EFI_EXTENDED_SAL_CACHE_SERVICES_PROTOCOL_GUID_LO,\r
+             EFI_EXTENDED_SAL_CACHE_SERVICES_PROTOCOL_GUID_HI,\r
+             SalCacheFlushFunctionId, \r
+             Arg2, \r
+             Arg3, \r
+             Arg4, \r
+             Arg5, \r
+             Arg6, \r
+             Arg7, \r
+             Arg8\r
+             );\r
+    break;\r
+\r
+  case EFI_SAL_CACHE_INIT:\r
+    return EsalCall (\r
+             EFI_EXTENDED_SAL_CACHE_SERVICES_PROTOCOL_GUID_LO,\r
+             EFI_EXTENDED_SAL_CACHE_SERVICES_PROTOCOL_GUID_HI,\r
+             SalCacheInitFunctionId, \r
+             Arg2, \r
+             Arg3, \r
+             Arg4, \r
+             Arg5, \r
+             Arg6, \r
+             Arg7, \r
+             Arg8\r
+             );\r
+    break;\r
+\r
+  case EFI_SAL_PCI_CONFIG_READ:\r
+    return EsalCall (\r
+             EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,\r
+             EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,\r
+             SalPciConfigReadFunctionId, \r
+             Arg2, \r
+             Arg3, \r
+             Arg4, \r
+             Arg5, \r
+             Arg6, \r
+             Arg7, \r
+             Arg8\r
+             );\r
+    break;\r
+\r
+  case EFI_SAL_PCI_CONFIG_WRITE:\r
+    return EsalCall (\r
+             EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,\r
+             EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,\r
+             SalPciConfigWriteFunctionId, \r
+             Arg2, \r
+             Arg3, \r
+             Arg4, \r
+             Arg5, \r
+             Arg6, \r
+             Arg7, \r
+             Arg8\r
+             );\r
+    break;\r
+\r
+  case EFI_SAL_FREQ_BASE:\r
+    return EsalCall (\r
+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+             EsalGetPlatformBaseFreqFunctionId, \r
+             Arg2, \r
+             Arg3, \r
+             Arg4, \r
+             Arg5, \r
+             Arg6, \r
+             Arg7, \r
+             Arg8\r
+             );\r
+    break;\r
+\r
+  case EFI_SAL_PHYSICAL_ID_INFO:\r
+    return EsalCall (\r
+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+             EsalPhysicalIdInfoFunctionId, \r
+             Arg2, \r
+             Arg3, \r
+             Arg4, \r
+             Arg5, \r
+             Arg6, \r
+             Arg7, \r
+             Arg8\r
+             );\r
+    break;\r
+\r
+  case EFI_SAL_UPDATE_PAL:\r
+    return EsalCall (\r
+             EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO,\r
+             EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,\r
+             EsalUpdatePalFunctionId, \r
+             Arg2, \r
+             Arg3, \r
+             Arg4, \r
+             Arg5, \r
+             Arg6, \r
+             Arg7, \r
+             Arg8\r
+             );\r
+    break;\r
+\r
+  default:\r
+    Regs.Status = EFI_SAL_INVALID_ARGUMENT;\r
+    return Regs;\r
+    break;\r
+  }\r
+}\r
diff --git a/MdePkg/Library/DxeSalLibEsal/DxeSalLibEsal.inf b/MdePkg/Library/DxeSalLibEsal/DxeSalLibEsal.inf
new file mode 100644 (file)
index 0000000..f40335c
--- /dev/null
@@ -0,0 +1,36 @@
+## @file\r
+#  This library implements the SAL Library Class using Extended SAL functions\r
+#\r
+#  Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  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
+#  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
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DxeSalLibEsal\r
+  FILE_GUID                      = 2B73B074-2E67-498b-82AC-CE38FB770FFC\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = SalLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION \r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IPF\r
+#\r
+\r
+[Sources.IPF]\r
+  DxeSalLibEsal.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+  ExtendedSalLib\r
diff --git a/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.c b/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.c
new file mode 100644 (file)
index 0000000..964f814
--- /dev/null
@@ -0,0 +1,179 @@
+/** @file\r
+  This library implements the Timer Library using the Extended SAL Stall Services Class.\r
+\r
+  Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  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 <PiDxe.h>\r
+\r
+#include <Protocol/ExtendedSalServiceClasses.h>\r
+\r
+#include <Library/TimerLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/ExtendedSalLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PalLib.h>\r
+\r
+/**\r
+  Stalls the CPU for at least the given number of microseconds.\r
+\r
+  This function wraps EsalStall function of Extended SAL Stall Services Class.\r
+  It stalls the CPU for the number of microseconds specified by MicroSeconds.\r
+\r
+  @param  MicroSeconds  The minimum number of microseconds to delay.\r
+\r
+  @return MicroSeconds\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+MicroSecondDelay (\r
+  IN      UINTN                     MicroSeconds\r
+  )\r
+{\r
+  EsalCall (\r
+    EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_LO,\r
+    EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_HI,\r
+    StallFunctionId, \r
+    MicroSeconds, \r
+    0, \r
+    0, \r
+    0, \r
+    0, \r
+    0, \r
+    0\r
+    );\r
+  return MicroSeconds;\r
+}\r
+\r
+/**\r
+  Stalls the CPU for at least the given number of nanoseconds.\r
+\r
+  This function wraps EsalStall function of Extended SAL Stall Services Class.\r
+  It stalls the CPU for the number of nanoseconds specified by NanoSeconds.\r
+\r
+  @param  NanoSeconds The minimum number of nanoseconds to delay.\r
+\r
+  @return NanoSeconds\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+NanoSecondDelay (\r
+  IN      UINTN                     NanoSeconds\r
+  )\r
+{\r
+  UINT64          MicroSeconds;\r
+\r
+  //\r
+  // The unit of ESAL Stall service is microsecond, so we turn the time interval\r
+  // from nanosecond to microsecond, using the ceiling value to ensure stalling\r
+  // at least the given number of nanoseconds.\r
+  //\r
+  MicroSeconds = DivU64x32 (NanoSeconds + 999, 1000);\r
+  EsalCall (\r
+    EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_LO,\r
+    EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_HI,\r
+    StallFunctionId, \r
+    MicroSeconds, \r
+    0, \r
+    0, \r
+    0, \r
+    0, \r
+    0, \r
+    0\r
+    );\r
+  return NanoSeconds;\r
+}\r
+\r
+/**\r
+  Retrieves the current value of a 64-bit free running performance counter.\r
+\r
+  Retrieves the current value of a 64-bit free running performance counter. The\r
+  counter can either count up by 1 or count down by 1. If the physical\r
+  performance counter counts by a larger increment, then the counter values\r
+  must be translated. The properties of the counter can be retrieved from\r
+  GetPerformanceCounterProperties().\r
+\r
+  @return The current value of the free running performance counter.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+GetPerformanceCounter (\r
+  VOID\r
+  )\r
+{\r
+  return AsmReadItc ();\r
+}\r
+\r
+/**\r
+  Retrieves the 64-bit frequency in Hz and the range of performance counter\r
+  values.\r
+\r
+  If StartValue is not NULL, then the value that the performance counter starts\r
+  with immediately after is it rolls over is returned in StartValue. If\r
+  EndValue is not NULL, then the value that the performance counter end with\r
+  immediately before it rolls over is returned in EndValue. The 64-bit\r
+  frequency of the performance counter in Hz is always returned. If StartValue\r
+  is less than EndValue, then the performance counter counts up. If StartValue\r
+  is greater than EndValue, then the performance counter counts down. For\r
+  example, a 64-bit free running counter that counts up would have a StartValue\r
+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter\r
+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.\r
+\r
+  @param  StartValue  The value the performance counter starts with when it\r
+                      rolls over.\r
+  @param  EndValue    The value that the performance counter ends with before\r
+                      it rolls over.\r
+\r
+  @return The frequency in Hz.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+GetPerformanceCounterProperties (\r
+  OUT      UINT64                    *StartValue,  OPTIONAL\r
+  OUT      UINT64                    *EndValue     OPTIONAL\r
+  )\r
+{\r
+  PAL_CALL_RETURN                   PalRet;\r
+  UINT64                            BaseFrequence;\r
+\r
+  //\r
+  // Get processor base frequency\r
+  //\r
+  PalRet = PalCall (PAL_FREQ_BASE, 0, 0, 0);\r
+  ASSERT (PalRet.Status == 0);\r
+  BaseFrequence = PalRet.r9;\r
+\r
+  //\r
+  // Get processor frequency ratio\r
+  //\r
+  PalRet = PalCall (PAL_FREQ_RATIOS, 0, 0, 0);\r
+  ASSERT (PalRet.Status == 0);\r
+\r
+  //\r
+  // Start value of counter is 0\r
+  //\r
+  if (StartValue != NULL) {\r
+    *StartValue = 0;\r
+  }\r
+\r
+  //\r
+  // End value of counter is 0xFFFFFFFFFFFFFFFF\r
+  //\r
+  if (EndValue != NULL) {\r
+    *EndValue = (UINT64)(-1);\r
+  }\r
+\r
+  return BaseFrequence * (PalRet.r11 >> 32) / (UINT32)PalRet.r11;\r
+}\r
diff --git a/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.inf b/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.inf
new file mode 100644 (file)
index 0000000..1993e4e
--- /dev/null
@@ -0,0 +1,39 @@
+## @file\r
+#  This library implements the Timer Library using the Extended SAL Stall Services Class.\r
+#\r
+#  Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  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
+#  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
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DxeTimerLibEsal\r
+  FILE_GUID                      = F672AE85-3769-4fb8-A5A0-70B38FB0A7C4\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = TimerLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION \r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IPF\r
+#\r
+\r
+[Sources]\r
+  DxeTimerLibEsal.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+  DebugLib\r
+  ExtendedSalLib\r
+  BaseLib\r
+  PalLib\r
index 9f61aaea04786cfa37a6bd963607db39a0ccbcc6..bb9d73610aaa431819c6acc027715aeacf6a2601 100644 (file)
   ##  @libraryclass  Provides library services to make PAL Calls.\r
   PalLib|Include/Library/PalLib.h\r
 \r
+  ##  @libraryclass  Provides library services to make Extended SAL Calls.\r
+  ExtendedSalLib|Include/Library/ExtendedSalLib.h\r
+  \r
 [Guids]\r
   #\r
   # GUID defined in UEFI2.1/UEFI2.0/EFI1.1\r
index cd7962dfebfb84eedc6043ae8d3d821932f20f24..d3ce1eeccb7f62bf44a753adc466b3f61f1dff8d 100644 (file)
   MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf\r
   MdePkg/Library/UefiPalLib/UefiPalLib.inf\r
   MdePkg/Library/UefiSalLib/UefiSalLib.inf\r
-\r
+  MdePkg/Library/DxeExtendedSalLib/DxeExtendedSalLib.inf\r
+  MdePkg/Library/DxeIoLibEsal/DxeIoLibEsal.inf\r
+  MdePkg/Library/DxePalLibEsal/DxePalLibEsal.inf\r
+  MdePkg/Library/DxePciLibEsal/DxePciLibEsal.inf\r
+  MdePkg/Library/DxePciSegmentLibEsal/DxePciSegmentLibEsal.inf\r
+  MdePkg/Library/DxeRuntimeExtendedSalLib/DxeRuntimeExtendedSalLib.inf\r
+  MdePkg/Library/DxeSalLibEsal/DxeSalLibEsal.inf\r
+  MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.inf  \r
+  \r
 [Components.EBC]\r
   MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf\r
-\r