diff --git a/MdeModulePkg/Include/Guid/ArmFfaRxTxBufferInfo.h b/MdeModulePkg/Include/Guid/ArmFfaRxTxBufferInfo.h index 0b8e2b6419..763dd61508 100644 --- a/MdeModulePkg/Include/Guid/ArmFfaRxTxBufferInfo.h +++ b/MdeModulePkg/Include/Guid/ArmFfaRxTxBufferInfo.h @@ -14,16 +14,22 @@ */ typedef struct ArmFfaRxTxBuffersInfo { /// Tx Buffer Address. - VOID *TxBufferAddr; + VOID *TxBufferAddr; /// Tx Buffer Size. - UINT64 TxBufferSize; + UINT64 TxBufferSize; /// Rx Buffer Address. - VOID *RxBufferAddr; + VOID *RxBufferAddr; /// Rx Buffer Size. - UINT64 RxBufferSize; + UINT64 RxBufferSize; + + /// Rx/Tx buffer should be remapped to permanent memory. + BOOLEAN RemapRequired; + + /// Rx/Tx buffer offset from its allocation base. + UINT64 RemapOffset; } ARM_FFA_RX_TX_BUFFER_INFO; extern EFI_GUID gArmFfaRxTxBufferInfoGuid; diff --git a/MdeModulePkg/Library/ArmFfaLib/ArmFfaPeiLib.c b/MdeModulePkg/Library/ArmFfaLib/ArmFfaPeiLib.c index eb55255901..a85a616f15 100644 --- a/MdeModulePkg/Library/ArmFfaLib/ArmFfaPeiLib.c +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaPeiLib.c @@ -34,25 +34,6 @@ #include "ArmFfaCommon.h" #include "ArmFfaRxTxMap.h" -/** - Update Rx/TX buffer information. - - @param BufferInfo Rx/Tx buffer information. - -**/ -STATIC -VOID -EFIAPI -UpdateRxTxBufferInfo ( - OUT ARM_FFA_RX_TX_BUFFER_INFO *BufferInfo - ) -{ - BufferInfo->TxBufferAddr = (VOID *)(UINTN)PcdGet64 (PcdFfaTxBuffer); - BufferInfo->TxBufferSize = PcdGet64 (PcdFfaTxRxPageCount) * EFI_PAGE_SIZE; - BufferInfo->RxBufferAddr = (VOID *)(UINTN)PcdGet64 (PcdFfaRxBuffer); - BufferInfo->RxBufferSize = PcdGet64 (PcdFfaTxRxPageCount) * EFI_PAGE_SIZE; -} - /** Notification service to be called when gEfiPeiMemoryDiscoveredPpiGuid is installed. This function change reamp Rx/Tx buffer with permanent memory from @@ -81,7 +62,6 @@ PeiServicesMemoryDiscoveredNotifyCallback ( IN VOID *Ppi ) { - EFI_STATUS Status; EFI_HOB_GUID_TYPE *RxTxBufferHob; ARM_FFA_RX_TX_BUFFER_INFO *BufferInfo; @@ -89,26 +69,7 @@ PeiServicesMemoryDiscoveredNotifyCallback ( ASSERT (RxTxBufferHob != NULL); BufferInfo = GET_GUID_HOB_DATA (RxTxBufferHob); - /* - * Temporary memory doesn't need to be free. - * otherwise PEI memory manager using permanent memory will be confused. - */ - PcdSet64S (PcdFfaTxBuffer, 0x00); - PcdSet64S (PcdFfaRxBuffer, 0x00); - - Status = ArmFfaLibRxTxUnmap (); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = ArmFfaLibRxTxMap (); - if (EFI_ERROR (Status)) { - return Status; - } - - UpdateRxTxBufferInfo (BufferInfo); - - return EFI_SUCCESS; + return RemapFfaRxTxBuffer (BufferInfo); } STATIC EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnPeiMemoryDiscovered = { @@ -138,6 +99,7 @@ ArmFfaPeiLibConstructor ( EFI_HOB_GUID_TYPE *RxTxBufferHob; ARM_FFA_RX_TX_BUFFER_INFO *BufferInfo; VOID *Dummy; + EFI_HOB_MEMORY_ALLOCATION *RxTxBufferAllocationHob; Status = ArmFfaLibCommonInit (); if (EFI_ERROR (Status)) { @@ -176,6 +138,11 @@ ArmFfaPeiLibConstructor ( UpdateRxTxBufferInfo (BufferInfo); + /* + * When permanent memory is used, gEfiPeiMemoryDiscoveredPpiGuid + * is installed. If gEfiPeiMemoryDiscoveredPpiGuid is found, + * It doesn't need to remap Rx/Tx buffer. + */ Status = (*PeiServices)->LocatePpi ( PeiServices, &gEfiPeiMemoryDiscoveredPpiGuid, @@ -183,10 +150,50 @@ ArmFfaPeiLibConstructor ( NULL, &Dummy ); - if (EFI_ERROR (Status)) { - Status = (*PeiServices)->NotifyPpi (PeiServices, &mNotifyOnPeiMemoryDiscovered); - ASSERT_EFI_ERROR (Status); + BufferInfo->RemapRequired = EFI_ERROR (Status); + } else { + BufferInfo = GET_GUID_HOB_DATA (RxTxBufferHob); + } + + if (BufferInfo->RemapRequired) { + /* + * If RxTxBufferAllocationHob can be found with gArmFfaRxTxBufferInfoGuid, + * This Rx/Tx buffer is mapped by ArmFfaSecLib. + */ + RxTxBufferAllocationHob = FindRxTxBufferAllocationHob (TRUE); + + /* + * Below case Rx/Tx buffer mapped by ArmPeiLib but in temporary memory. + */ + if (RxTxBufferAllocationHob == NULL) { + RxTxBufferAllocationHob = FindRxTxBufferAllocationHob (FALSE); + ASSERT (RxTxBufferAllocationHob != NULL); + BufferInfo->RemapOffset = + (UINTN)((EFI_PHYSICAL_ADDRESS)((UINTN)BufferInfo->TxBufferAddr) - + RxTxBufferAllocationHob->AllocDescriptor.MemoryBaseAddress); + + CopyGuid ( + &RxTxBufferAllocationHob->AllocDescriptor.Name, + &gArmFfaRxTxBufferInfoGuid + ); } + + Status = (*PeiServices)->NotifyPpi (PeiServices, &mNotifyOnPeiMemoryDiscovered); + + /* + * Failed to register NotifyPpi. + * In this case, return ERROR to make failure of load for PPI + * and postpone to remap to other PEIM. + */ + if (EFI_ERROR (Status)) { + return Status; + } + + /* + * Change RemapRequired to FALSE here to prevent other PEIM from + * registering notification again. + */ + BufferInfo->RemapRequired = FALSE; } return EFI_SUCCESS; diff --git a/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMap.c b/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMap.c index 37d3e80c3c..528058e607 100644 --- a/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMap.c +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMap.c @@ -19,12 +19,15 @@ #include #include #include +#include #include #include #include #include +#include + #include "ArmFfaCommon.h" #include "ArmFfaRxTxMap.h" @@ -270,3 +273,197 @@ ArmFfaLibRxTxUnmap ( return EFI_SUCCESS; } + +/** + Update Rx/TX buffer information. + + @param BufferInfo Rx/Tx buffer information. + +**/ +VOID +EFIAPI +UpdateRxTxBufferInfo ( + OUT ARM_FFA_RX_TX_BUFFER_INFO *BufferInfo + ) +{ + BufferInfo->TxBufferAddr = (VOID *)(UINTN)PcdGet64 (PcdFfaTxBuffer); + BufferInfo->TxBufferSize = PcdGet64 (PcdFfaTxRxPageCount) * EFI_PAGE_SIZE; + BufferInfo->RxBufferAddr = (VOID *)(UINTN)PcdGet64 (PcdFfaRxBuffer); + BufferInfo->RxBufferSize = PcdGet64 (PcdFfaTxRxPageCount) * EFI_PAGE_SIZE; +} + +/** + Find Rx/TX buffer memory allocation hob. + + @param UseGuid Find MemoryAllocationHob using gArmFfaRxTxBufferInfoGuid. + + @retval MemoryAllocationHob + @retval NULL No memory allocation hob related to Rx/Tx buffer + +**/ +EFI_HOB_MEMORY_ALLOCATION * +EFIAPI +FindRxTxBufferAllocationHob ( + IN BOOLEAN UseGuid + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHob; + EFI_PHYSICAL_ADDRESS BufferBase; + UINT64 BufferSize; + EFI_PHYSICAL_ADDRESS MemoryBase; + UINT64 MemorySize; + + BufferBase = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdFfaTxBuffer); + BufferSize = PcdGet64 (PcdFfaTxRxPageCount) * EFI_PAGE_SIZE * 2; + + if (!UseGuid && (BufferBase == 0x00)) { + return NULL; + } + + MemoryAllocationHob = NULL; + Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION); + + while (Hob.Raw != NULL) { + if (Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiConventionalMemory) { + continue; + } + + MemoryBase = Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress; + MemorySize = Hob.MemoryAllocation->AllocDescriptor.MemoryLength; + + if ((!UseGuid && (BufferBase >= MemoryBase) && + ((BufferBase + BufferSize) <= (MemoryBase + MemorySize))) || + (UseGuid && CompareGuid ( + &gArmFfaRxTxBufferInfoGuid, + &Hob.MemoryAllocation->AllocDescriptor.Name + ))) + { + MemoryAllocationHob = (EFI_HOB_MEMORY_ALLOCATION *)Hob.Raw; + break; + } + + Hob.Raw = GET_NEXT_HOB (Hob); + Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw); + } // while + + return MemoryAllocationHob; +} + +/** + Remap Rx/TX buffer with converted Rx/Tx Buffer address after + using permanent memory. + + @param[out] BufferInfo BufferInfo + + @retval EFI_SUCCESS Success + @retval EFI_NOT_FOUND No memory allocation hob related to Rx/Tx buffer + +**/ +EFI_STATUS +EFIAPI +RemapFfaRxTxBuffer ( + OUT ARM_FFA_RX_TX_BUFFER_INFO *BufferInfo + ) +{ + EFI_STATUS Status; + ARM_FFA_ARGS FfaArgs; + UINTN NewBufferBase; + UINTN NewTxBuffer; + UINTN NewRxBuffer; + UINTN Property1; + UINTN Property2; + UINTN MinSizeAndAlign; + EFI_HOB_MEMORY_ALLOCATION *RxTxBufferAllocationHob; + + RxTxBufferAllocationHob = FindRxTxBufferAllocationHob (TRUE); + if (RxTxBufferAllocationHob == NULL) { + return EFI_NOT_FOUND; + } + + Status = ArmFfaLibGetFeatures ( + ARM_FID_FFA_RXTX_MAP, + FFA_RXTX_MAP_INPUT_PROPERTY_DEFAULT, + &Property1, + &Property2 + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: Failed to get RX/TX buffer property... Status: %r\n", + __func__, + Status + )); + return Status; + } + + MinSizeAndAlign = + ((Property1 >> + ARM_FFA_BUFFER_MINSIZE_AND_ALIGN_SHIFT) & + ARM_FFA_BUFFER_MINSIZE_AND_ALIGN_MASK); + + switch (MinSizeAndAlign) { + case ARM_FFA_BUFFER_MINSIZE_AND_ALIGN_4K: + MinSizeAndAlign = SIZE_4KB; + break; + case ARM_FFA_BUFFER_MINSIZE_AND_ALIGN_16K: + MinSizeAndAlign = SIZE_16KB; + break; + case ARM_FFA_BUFFER_MINSIZE_AND_ALIGN_64K: + MinSizeAndAlign = SIZE_64KB; + break; + default: + DEBUG ((DEBUG_ERROR, "%a: Invalid MinSizeAndAlign: 0x%x\n", __func__, MinSizeAndAlign)); + return EFI_UNSUPPORTED; + } + + ZeroMem (&FfaArgs, sizeof (ARM_FFA_ARGS)); + FfaArgs.Arg0 = ARM_FID_FFA_RXTX_UNMAP; + FfaArgs.Arg1 = (gPartId << ARM_FFA_SOURCE_EP_SHIFT); + + ArmCallFfa (&FfaArgs); + Status = FfaArgsToEfiStatus (&FfaArgs); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to unmap Rx/Tx buffer. Status: %r\n", __func__, Status)); + return Status; + } + + PcdSet64S (PcdFfaTxBuffer, 0x00); + PcdSet64S (PcdFfaRxBuffer, 0x00); + + NewBufferBase = (UINTN)RxTxBufferAllocationHob->AllocDescriptor.MemoryBaseAddress + BufferInfo->RemapOffset; + NewTxBuffer = NewBufferBase; + NewRxBuffer = NewTxBuffer + (PcdGet64 (PcdFfaTxRxPageCount) * EFI_PAGE_SIZE); + + ZeroMem (&FfaArgs, sizeof (ARM_FFA_ARGS)); + FfaArgs.Arg0 = ARM_FID_FFA_RXTX_MAP; + FfaArgs.Arg1 = NewTxBuffer; + FfaArgs.Arg2 = NewRxBuffer; + + /* + * PcdFfaTxRxPageCount sets with count of EFI_PAGE_SIZE granularity + * But, PageCounts for Tx/Rx buffer should set with + * count of Tx/Rx Buffer's MinSizeAndAlign. granularity. + */ + FfaArgs.Arg3 = PcdGet64 (PcdFfaTxRxPageCount) / EFI_SIZE_TO_PAGES (MinSizeAndAlign); + + ArmCallFfa (&FfaArgs); + Status = FfaArgsToEfiStatus (&FfaArgs); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to map with new Rx/Tx buffer. Status: %r\n", __func__, Status)); + return Status; + } + + PcdSet64S (PcdFfaTxBuffer, NewTxBuffer); + PcdSet64S (PcdFfaRxBuffer, NewRxBuffer); + + UpdateRxTxBufferInfo (BufferInfo); + + /* + * Remap is done. clear to AllocDesciptor.Name + * so that unnecessary remap happen again. + */ + ZeroMem (&RxTxBufferAllocationHob->AllocDescriptor.Name, sizeof (EFI_GUID)); + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMap.h b/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMap.h index 6c6bfaa3cd..5140865b5f 100644 --- a/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMap.h +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMap.h @@ -17,6 +17,8 @@ #ifndef ARM_FFA_RX_TX_MAP_LIB_H_ #define ARM_FFA_RX_TX_MAP_LIB_H_ +#include + /** Mapping Rx/Tx buffers. This function is only called in ArmFfaLibConstructor because @@ -51,4 +53,47 @@ ArmFfaLibRxTxUnmap ( IN VOID ); +/** + Update Rx/TX buffer information. + + @param BufferInfo Rx/Tx buffer information. + +**/ +VOID +EFIAPI +UpdateRxTxBufferInfo ( + OUT ARM_FFA_RX_TX_BUFFER_INFO *BufferInfo + ); + +/** + Find Rx/TX buffer memory allocation hob. + + @param UseGuid Find MemoryAllocationHob using Guid. + + @retval MemoryAllocationHob + @retval NULL No memory allocation hob related to Rx/Tx buffer + +**/ +EFI_HOB_MEMORY_ALLOCATION * +EFIAPI +FindRxTxBufferAllocationHob ( + IN BOOLEAN UseGuid + ); + +/** + Remap Rx/TX buffer with converted Rx/Tx Buffer address after + using permanent memory. + + @param[out] BufferInfo BufferInfo + + @retval EFI_SUCCESS Success + @retval EFI_NOT_FOUND No memory allocation hob related to Rx/Tx buffer + +**/ +EFI_STATUS +EFIAPI +RemapFfaRxTxBuffer ( + IN OUT ARM_FFA_RX_TX_BUFFER_INFO *BufferInfo + ); + #endif diff --git a/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmCoreLib.inf b/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmCoreLib.inf index 863836af39..67b7b5c24a 100644 --- a/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmCoreLib.inf +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmCoreLib.inf @@ -19,9 +19,9 @@ [Sources] ArmFfaCommon.h ArmFfaCommon.c - ArmFfaStandaloneMmLib.c ArmFfaRxTxMap.h - ArmFfaRxTxMapStmm.c + ArmFfaStandaloneMmRxTxMap.c + ArmFfaStandaloneMmLib.c [Packages] MdePkg/MdePkg.dec diff --git a/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmLib.inf b/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmLib.inf index 019eab3e58..532dc195c6 100644 --- a/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmLib.inf +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmLib.inf @@ -19,9 +19,9 @@ [Sources] ArmFfaCommon.h ArmFfaCommon.c - ArmFfaStandaloneMmLib.c ArmFfaRxTxMap.h - ArmFfaRxTxMapStmm.c + ArmFfaStandaloneMmRxTxMap.c + ArmFfaStandaloneMmLib.c [Packages] MdePkg/MdePkg.dec diff --git a/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMapStmm.c b/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmRxTxMap.c similarity index 84% rename from MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMapStmm.c rename to MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmRxTxMap.c index e7c1951210..2d087ed5f2 100644 --- a/MdeModulePkg/Library/ArmFfaLib/ArmFfaRxTxMapStmm.c +++ b/MdeModulePkg/Library/ArmFfaLib/ArmFfaStandaloneMmRxTxMap.c @@ -1,7 +1,7 @@ /** @file Arm Ffa library common code. - Copyright (c) 2024, Arm Limited. All rights reserved.
+ Copyright (c) 2024-2025, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @par Glossary: @@ -11,8 +11,7 @@ - Arm Firmware Framework for Arm A-Profile v1.3 ALP1: [https://developer.arm.com/documentation/den0077/l] **/ -#include -#include +#include #include #include @@ -319,3 +318,65 @@ ArmFfaLibRxTxUnmap ( return EFI_SUCCESS; } + +/** + Update Rx/TX buffer information. + + @param BufferInfo Rx/Tx buffer information. + +**/ +VOID +EFIAPI +UpdateRxTxBufferInfo ( + OUT ARM_FFA_RX_TX_BUFFER_INFO *BufferInfo + ) +{ + /* + * StandaloneMm doesn't use Rx/Tx buffer. + */ + return; +} + +/** + Find Rx/TX buffer memory allocation hob. + + @param UseGuid Find MemoryAllocationHob using Guid. + + @retval MemoryAllocationHob + @retval NULL No memory allocation hob related to Rx/Tx buffer + +**/ +EFI_HOB_MEMORY_ALLOCATION * +EFIAPI +FindRxTxBufferAllocationHob ( + IN BOOLEAN UseGuid + ) +{ + /* + * StandaloneMm doesn't use Rx/Tx buffer. + */ + return NULL; +} + +/** + Remap Rx/TX buffer with converted Rx/Tx Buffer address after + using permanent memory. + + @param[out] BufferInfo BufferInfo + + @retval EFI_SUCCESS Success + @retval EFI_NOT_FOUND No memory allocation hob related to Rx/Tx buffer + +**/ +EFI_STATUS +EFIAPI +RemapFfaRxTxBuffer ( + OUT ARM_FFA_RX_TX_BUFFER_INFO *BufferInfo + ) +{ + /* + * StandaloneMm doesn't use Rx/Tx buffer. + * So, return EFI_UNSUPPORTED. + */ + return EFI_UNSUPPORTED; +}