MdeModulePkg/Library: commonize some duplicate code in ArmFfaLib

Some of code for handling Rx/Tx buffer is duplicate.
This patch commonize some of duplication routine used in
Rx/Tx buffer related functions.

Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
This commit is contained in:
Levi Yun
2025-06-06 15:16:07 +01:00
committed by mergify[bot]
parent a7e27682cf
commit 5a2713ec2b
5 changed files with 194 additions and 225 deletions

View File

@@ -21,12 +21,15 @@
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <IndustryStandard/ArmFfaSvc.h>
#include <IndustryStandard/ArmFfaPartInfo.h>
#include <IndustryStandard/ArmStdSmc.h>
#include <Guid/ArmFfaRxTxBufferInfo.h>
#include "ArmFfaCommon.h"
BOOLEAN gFfaSupported;
@@ -752,3 +755,146 @@ ArmFfaLibCommonInit (
return EFI_SUCCESS;
}
/**
Get first Rx/Tx Buffer allocation hob.
If UseGuid is TRUE, BufferAddr and BufferSize parameters are ignored.
@param[in] BufferAddr Buffer address
@param[in] BufferSize Buffer Size
@param[in] UseGuid Find MemoryAllocationHob using gArmFfaRxTxBufferInfoGuid.
@retval NULL Not found
@retval Other MemoryAllocationHob related to Rx/Tx buffer
**/
EFI_HOB_MEMORY_ALLOCATION *
EFIAPI
GetRxTxBufferAllocationHob (
IN EFI_PHYSICAL_ADDRESS BufferAddr,
IN UINT64 BufferSize,
IN BOOLEAN UseGuid
)
{
EFI_PEI_HOB_POINTERS Hob;
EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHob;
EFI_PHYSICAL_ADDRESS MemoryBase;
UINT64 MemorySize;
if (!UseGuid && (BufferAddr == 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 && (BufferAddr >= MemoryBase) &&
((BufferAddr + 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);
}
return MemoryAllocationHob;
}
/**
Get Rx/Tx buffer MinSizeAndAign and MaxSize
@param[out] MinSizeAndAlign Minimum size of Buffer.
@retval EFI_SUCCESS
@retval EFI_UNSUPPORTED Wrong min size received from SPMC
@retval EFI_INVALID_PARAMETER Wrong buffer size
@retval Others Failure of ArmFfaLibGetFeatures()
**/
EFI_STATUS
EFIAPI
GetRxTxBufferMinSizeAndAlign (
OUT UINTN *MinSizeAndAlign
)
{
EFI_STATUS Status;
UINTN MinAndAlign;
UINTN MaxSize;
UINTN Property1;
UINTN Property2;
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;
}
MinAndAlign =
((Property1 >>
ARM_FFA_BUFFER_MINSIZE_AND_ALIGN_SHIFT) &
ARM_FFA_BUFFER_MINSIZE_AND_ALIGN_MASK);
switch (MinAndAlign) {
case ARM_FFA_BUFFER_MINSIZE_AND_ALIGN_4K:
MinAndAlign = SIZE_4KB;
break;
case ARM_FFA_BUFFER_MINSIZE_AND_ALIGN_16K:
MinAndAlign = SIZE_16KB;
break;
case ARM_FFA_BUFFER_MINSIZE_AND_ALIGN_64K:
MinAndAlign = SIZE_64KB;
break;
default:
DEBUG ((DEBUG_ERROR, "%a: Invalid MinSizeAndAlign: 0x%x\n", __func__, MinAndAlign));
return EFI_UNSUPPORTED;
}
MaxSize =
(((Property1 >>
ARM_FFA_BUFFER_MAXSIZE_PAGE_COUNT_SHIFT) &
ARM_FFA_BUFFER_MAXSIZE_PAGE_COUNT_MASK));
MaxSize = ((MaxSize == 0) ? MAX_UINTN : (MaxSize * MinAndAlign));
if ((MinAndAlign > (PcdGet64 (PcdFfaTxRxPageCount) * EFI_PAGE_SIZE)) ||
(MaxSize < (PcdGet64 (PcdFfaTxRxPageCount) * EFI_PAGE_SIZE)))
{
DEBUG ((
DEBUG_ERROR,
"%a: Buffer is too small! MinSize: 0x%x, MaxSize: 0x%x, PageCount: %d\n",
__func__,
MinAndAlign,
MaxSize,
PcdGet64 (PcdFfaTxRxPageCount)
));
return EFI_INVALID_PARAMETER;
}
*MinSizeAndAlign = MinAndAlign;
return EFI_SUCCESS;
}

View File

@@ -49,4 +49,41 @@ ArmFfaLibCommonInit (
IN VOID
);
/**
Get first Rx/Tx Buffer allocation hob.
If UseGuid is TRUE, BufferAddr and BufferSize parameters are ignored.
@param[in] BufferAddr Buffer address
@param[in] BufferSize Buffer Size
@param[in] UseGuid Find MemoryAllocationHob using gArmFfaRxTxBufferInfoGuid.
@retval NULL Not found
@retval Other MemoryAllocationHob related to Rx/Tx buffer
**/
EFI_HOB_MEMORY_ALLOCATION *
EFIAPI
GetRxTxBufferAllocationHob (
IN EFI_PHYSICAL_ADDRESS BufferAddr,
IN UINT64 BufferSize,
IN BOOLEAN UseGuid
);
/**
Get Rx/Tx buffer MinSizeAndAign and MaxSize
@param[out] MinSizeAndAlign Minimum size of Buffer.
@retval EFI_SUCCESS
@retval EFI_UNSUPPORTED Wrong min size received from SPMC
@retval EFI_INVALID_PARAMETER Wrong buffer size
@retval Others Failure of ArmFfaLibGetFeatures()
**/
EFI_STATUS
EFIAPI
GetRxTxBufferMinSizeAndAlign (
OUT UINTN *MinSizeAndAlign
);
#endif

View File

@@ -101,10 +101,7 @@ ArmFfaLibRxTxMap (
{
EFI_STATUS Status;
ARM_FFA_ARGS FfaArgs;
UINTN Property1;
UINTN Property2;
UINTN MinSizeAndAlign;
UINTN MaxSize;
VOID *Buffers;
VOID *TxBuffer;
VOID *RxBuffer;
@@ -122,65 +119,11 @@ ArmFfaLibRxTxMap (
return EFI_ALREADY_STARTED;
}
Status = ArmFfaLibGetFeatures (
ARM_FID_FFA_RXTX_MAP,
FFA_RXTX_MAP_INPUT_PROPERTY_DEFAULT,
&Property1,
&Property2
);
Status = GetRxTxBufferMinSizeAndAlign (&MinSizeAndAlign);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: Failed to get RX/TX buffer property... Status: %r\n",
__func__,
Status
));
return Status;
}
ZeroMem (&FfaArgs, sizeof (ARM_FFA_ARGS));
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;
}
MaxSize =
(((Property1 >>
ARM_FFA_BUFFER_MAXSIZE_PAGE_COUNT_SHIFT) &
ARM_FFA_BUFFER_MAXSIZE_PAGE_COUNT_MASK));
MaxSize = ((MaxSize == 0) ? MAX_UINTN : (MaxSize * MinSizeAndAlign));
if ((MinSizeAndAlign > (PcdGet64 (PcdFfaTxRxPageCount) * EFI_PAGE_SIZE)) ||
(MaxSize < (PcdGet64 (PcdFfaTxRxPageCount) * EFI_PAGE_SIZE)))
{
DEBUG ((
DEBUG_ERROR,
"%a: Buffer is too small! MinSize: 0x%x, MaxSize: 0x%x, PageCount: %d\n",
__func__,
MinSizeAndAlign,
MaxSize,
PcdGet64 (PcdFfaTxRxPageCount)
));
return EFI_INVALID_PARAMETER;
}
Buffers = AllocateAlignedPages ((PcdGet64 (PcdFfaTxRxPageCount) * 2), MinSizeAndAlign);
if (Buffers == NULL) {
return EFI_OUT_OF_RESOURCES;
@@ -189,6 +132,7 @@ ArmFfaLibRxTxMap (
TxBuffer = Buffers;
RxBuffer = Buffers + BufferSize;
ZeroMem (&FfaArgs, sizeof (ARM_FFA_ARGS));
FfaArgs.Arg0 = ARM_FID_FFA_RXTX_MAP;
FfaArgs.Arg1 = (UINTN)TxBuffer;
FfaArgs.Arg2 = (UINTN)RxBuffer;
@@ -307,47 +251,13 @@ 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;
EFI_PHYSICAL_ADDRESS BufferBase;
UINT64 BufferSize;
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;
return GetRxTxBufferAllocationHob (BufferBase, BufferSize, UseGuid);
}
/**
@@ -371,8 +281,6 @@ RemapFfaRxTxBuffer (
UINTN NewBufferBase;
UINTN NewTxBuffer;
UINTN NewRxBuffer;
UINTN Property1;
UINTN Property2;
UINTN MinSizeAndAlign;
EFI_HOB_MEMORY_ALLOCATION *RxTxBufferAllocationHob;
@@ -381,41 +289,7 @@ RemapFfaRxTxBuffer (
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;
}
Status = GetRxTxBufferMinSizeAndAlign (&MinSizeAndAlign);
ZeroMem (&FfaArgs, sizeof (ARM_FFA_ARGS));
FfaArgs.Arg0 = ARM_FID_FFA_RXTX_UNMAP;

View File

@@ -297,47 +297,13 @@ 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;
EFI_PHYSICAL_ADDRESS BufferBase;
UINT64 BufferSize;
BufferBase = (EFI_PHYSICAL_ADDRESS)((UINTN)mTxBuffer);
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);
}
return MemoryAllocationHob;
return GetRxTxBufferAllocationHob (BufferBase, BufferSize, UseGuid);
}
/**

View File

@@ -112,10 +112,7 @@ ArmFfaLibRxTxMap (
{
EFI_STATUS Status;
ARM_FFA_ARGS FfaArgs;
UINTN Property1;
UINTN Property2;
UINTN MinSizeAndAlign;
UINTN MaxSize;
VOID *Buffers;
VOID *TxBuffer;
VOID *RxBuffer;
@@ -131,63 +128,11 @@ ArmFfaLibRxTxMap (
return EFI_ALREADY_STARTED;
}
Status = ArmFfaLibGetFeatures (
ARM_FID_FFA_RXTX_MAP,
FFA_RXTX_MAP_INPUT_PROPERTY_DEFAULT,
&Property1,
&Property2
);
Status = GetRxTxBufferMinSizeAndAlign (&MinSizeAndAlign);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: Failed to get RX/TX buffer property... Status: %r\n",
__func__,
Status
));
return Status;
}
ZeroMem (&FfaArgs, sizeof (ARM_FFA_ARGS));
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;
}
MaxSize = (Property1 >> ARM_FFA_BUFFER_MAXSIZE_PAGE_COUNT_SHIFT) &
ARM_FFA_BUFFER_MAXSIZE_PAGE_COUNT_MASK;
MaxSize = ((MaxSize == 0) ? MAX_UINTN : (MaxSize * MinSizeAndAlign));
if ((MinSizeAndAlign > (PcdGet64 (PcdFfaTxRxPageCount) * EFI_PAGE_SIZE)) ||
(MaxSize < (PcdGet64 (PcdFfaTxRxPageCount) * EFI_PAGE_SIZE)))
{
DEBUG ((
DEBUG_ERROR,
"%a: Buffer is too small! MinSize: 0x%x, MaxSize: 0x%x, PageCount: %d\n",
__func__,
MinSizeAndAlign,
MaxSize,
PcdGet64 (PcdFfaTxRxPageCount)
));
return EFI_INVALID_PARAMETER;
}
Buffers = AllocateAlignedPages ((PcdGet64 (PcdFfaTxRxPageCount) * 2), MinSizeAndAlign);
if (Buffers == NULL) {
return EFI_OUT_OF_RESOURCES;
@@ -197,6 +142,7 @@ ArmFfaLibRxTxMap (
TxBuffer = Buffers;
RxBuffer = Buffers + BufferSize;
ZeroMem (&FfaArgs, sizeof (ARM_FFA_ARGS));
FfaArgs.Arg0 = ARM_FID_FFA_RXTX_MAP;
FfaArgs.Arg1 = (UINTN)TxBuffer;
FfaArgs.Arg2 = (UINTN)RxBuffer;