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