Liming,

Minor comments inline below.

Reviewed-by: Star Zeng <star.z...@intel.com>

On 2015/8/18 17:25, Liming Gao wrote:
Two new APIs LibPatchPcdSetPtrAndSize() and LibPatchPcdSetPtrAndSizeS()
are added to catch the size of the updated VOID* PCD value buffer, then
PcdGetSize() API can return the actual size.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Liming Gao <liming....@intel.com>
---
  MdePkg/Include/Library/PcdLib.h      |  75 ++++++++++++++++++++++-
  MdePkg/Library/DxePcdLib/DxePcdLib.c | 111 +++++++++++++++++++++++++++++++++++
  MdePkg/Library/PeiPcdLib/PeiPcdLib.c | 111 +++++++++++++++++++++++++++++++++++
  3 files changed, 295 insertions(+), 2 deletions(-)

diff --git a/MdePkg/Include/Library/PcdLib.h b/MdePkg/Include/Library/PcdLib.h
index 962d442..0bbccb3 100644
--- a/MdePkg/Include/Library/PcdLib.h
+++ b/MdePkg/Include/Library/PcdLib.h
@@ -340,12 +340,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.

    @return Return the pointer to the Buffer that was set.

  **/
  #define PatchPcdSetPtr(TokenName, Size, Buffer) \
-                                            LibPatchPcdSetPtr (                
        \
-                                              _gPcd_BinaryPatch_##TokenName,   
        \
+                                            LibPatchPcdSetPtrAndSize (         
        \
+                                              (VOID 
*)_gPcd_BinaryPatch_##TokenName,   \
+                                              
&_gPcd_BinaryPatch_Size_##TokenName,     \
                                                
(UINTN)_PCD_PATCHABLE_##TokenName##_SIZE, \
                                                (Size),                         
         \
                                                (Buffer)                        
         \
                                                )
  /**
@@ -2104,10 +2105,80 @@ LibPatchPcdSetPtrS (
    IN       UINTN    MaximumDatumSize,
    IN OUT   UINTN    *SizeOfBuffer,
    IN CONST VOID     *Buffer
    );

+/**
+  Sets a value and size of a patchable PCD entry that is type pointer.
+
+  Sets the PCD entry specified by PatchVariable to the value specified by 
Buffer
+  and SizeOfBuffer. Buffer is returned.  If SizeOfBuffer is greater than
+  MaximumDatumSize, then set SizeOfBuffer to MaximumDatumSize and return
+  NULL to indicate that the set operation was not actually performed.
+  If SizeOfBuffer is set to MAX_ADDRESS, then SizeOfBuffer must be set to
+  MaximumDatumSize and NULL must be returned.
+
+  If PatchVariable is NULL, then ASSERT().
+  If SizeOfPatchVariable is NULL, then ASSERT().
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+
+  @param[out] PatchVariable     A pointer to the global variable in a module 
that is
+                                the target of the set operation.
+  @param[out] SizeOfPatchVariable A pointer to the size, in bytes, of 
PatchVariable.
+  @param[in] MaximumDatumSize   The maximum size allowed for the PCD entry 
specified by PatchVariable.
+  @param[in, out] SizeOfBuffer  A pointer to the size, in bytes, of Buffer.
+  @param[in] Buffer             A pointer to the buffer to used to set the 
target variable.
+
+  @return Return the pointer to the Buffer that was set.
+
+**/
+VOID *
+EFIAPI
+LibPatchPcdSetPtrAndSize (
+  OUT       VOID        *PatchVariable,
+  OUT       UINTN       *SizeOfPatchVariable,
+  IN        UINTN       MaximumDatumSize,
+  IN OUT    UINTN       *SizeOfBuffer,
+  IN CONST  VOID        *Buffer
+  );
+
+/**
+  Sets a value and size of a patchable PCD entry that is type pointer.
+
+  Sets the PCD entry specified by PatchVariable to the value specified
+  by Buffer and SizeOfBuffer. If SizeOfBuffer is greater than MaximumDatumSize,
+  then set SizeOfBuffer to MaximumDatumSize and return RETURN_INVALID_PARAMETER
+  to indicate that the set operation was not actually performed.
+  If SizeOfBuffer is set to MAX_ADDRESS, then SizeOfBuffer must be set to
+  MaximumDatumSize and RETURN_INVALID_PARAMETER must be returned.
+
+  If PatchVariable is NULL, then ASSERT().
+  If SizeOfPatchVariable is NULL, then ASSERT().
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+
+  @param[in] PatchVariable      A pointer to the global variable in a module 
that is
+                                the target of the set operation.

The in should be out actually to be same with LibPatchPcdSetPtrAndSize()?
And should we also update LibPatchPcdSetPtr() and LibPatchPcdSetPtrS() to align with this?

+  @param[out] SizeOfPatchVariable A pointer to the size, in bytes, of 
PatchVariable.
+  @param[in] MaximumDatumSize   The maximum size allowed for the PCD entry 
specified by PatchVariable.
+  @param[in, out] SizeOfBuffer  A pointer to the size, in bytes, of Buffer.
+  @param[in] Buffer             A pointer to the buffer to used to set the 
target variable.
+
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPatchPcdSetPtrAndSizeS (
+  OUT      VOID     *PatchVariable,
+  OUT      UINTN    *SizeOfPatchVariable,
+  IN       UINTN    MaximumDatumSize,
+  IN OUT   UINTN    *SizeOfBuffer,
+  IN CONST VOID     *Buffer
+  );
+
  typedef enum {
    PCD_TYPE_8,
    PCD_TYPE_16,
    PCD_TYPE_32,
    PCD_TYPE_64,
diff --git a/MdePkg/Library/DxePcdLib/DxePcdLib.c 
b/MdePkg/Library/DxePcdLib/DxePcdLib.c
index 431ee72..df48790 100644
--- a/MdePkg/Library/DxePcdLib/DxePcdLib.c
+++ b/MdePkg/Library/DxePcdLib/DxePcdLib.c
@@ -1446,10 +1446,121 @@ LibPatchPcdSetPtrS (
    CopyMem (PatchVariable, Buffer, *SizeOfBuffer);

    return RETURN_SUCCESS;
  }

+
+/**
+  Sets a value and size of a patchable PCD entry that is type pointer.
+
+  Sets the PCD entry specified by PatchVariable to the value specified by 
Buffer
+  and SizeOfBuffer.  Buffer is returned.  If SizeOfBuffer is greater than
+  MaximumDatumSize, then set SizeOfBuffer to MaximumDatumSize and return
+  NULL to indicate that the set operation was not actually performed.
+  If SizeOfBuffer is set to MAX_ADDRESS, then SizeOfBuffer must be set to
+  MaximumDatumSize and NULL must be returned.
+
+  If PatchVariable is NULL, then ASSERT().
+  If SizeOfPatchVariable is NULL, then ASSERT().
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+
+  @param[out] PatchVariable     A pointer to the global variable in a module 
that is
+                                the target of the set operation.
+  @param[out] SizeOfPatchVariable A pointer to the size, in bytes, of 
PatchVariable.
+  @param[in] MaximumDatumSize   The maximum size allowed for the PCD entry 
specified by PatchVariable.
+  @param[in, out] SizeOfBuffer  A pointer to the size, in bytes, of Buffer.
+  @param[in] Buffer             A pointer to the buffer to used to set the 
target variable.
+
+  @return Return the pointer to the buffer been set.
+
+**/
+VOID *
+EFIAPI
+LibPatchPcdSetPtrAndSize (
+  OUT       VOID        *PatchVariable,
+  OUT       UINTN       *SizeOfPatchVariable,
+  IN        UINTN       MaximumDatumSize,
+  IN OUT    UINTN       *SizeOfBuffer,
+  IN CONST  VOID        *Buffer
+  )
+{
+  ASSERT (PatchVariable != NULL);
+  ASSERT (SizeOfPatchVariable != NULL);
+  ASSERT (SizeOfBuffer  != NULL);
+
+  if (*SizeOfBuffer > 0) {
+    ASSERT (Buffer != NULL);
+  }
+
+  if ((*SizeOfBuffer > MaximumDatumSize) ||
+      (*SizeOfBuffer == MAX_ADDRESS)) {
+    *SizeOfBuffer = MaximumDatumSize;
+    return NULL;
+  }
+
+  CopyMem (PatchVariable, Buffer, *SizeOfBuffer);
+  *SizeOfPatchVariable = *SizeOfBuffer;
+
+  return (VOID *) Buffer;
+}
+
+/**
+  Sets a value and size of a patchable PCD entry that is type pointer.
+
+  Sets the PCD entry specified by PatchVariable to the value specified
+  by Buffer and SizeOfBuffer. If SizeOfBuffer is greater than MaximumDatumSize,
+  then set SizeOfBuffer to MaximumDatumSize and return RETURN_INVALID_PARAMETER
+  to indicate that the set operation was not actually performed.
+  If SizeOfBuffer is set to MAX_ADDRESS, then SizeOfBuffer must be set to
+  MaximumDatumSize and RETURN_INVALID_PARAMETER must be returned.
+
+  If PatchVariable is NULL, then ASSERT().
+  If SizeOfPatchVariable is NULL, then ASSERT().
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+
+  @param[out] PatchVariable     A pointer to the global variable in a module 
that is
+                                the target of the set operation.
+  @param[out] SizeOfPatchVariable A pointer to the size, in bytes, of 
PatchVariable.
+  @param[in] MaximumDatumSize   The maximum size allowed for the PCD entry 
specified by PatchVariable.
+  @param[in, out] SizeOfBuffer  A pointer to the size, in bytes, of Buffer.
+  @param[in] Buffer             A pointer to the buffer to used to set the 
target variable.
+
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPatchPcdSetPtrAndSizeS (
+  OUT      VOID     *PatchVariable,
+  OUT      UINTN    *SizeOfPatchVariable,
+  IN       UINTN    MaximumDatumSize,
+  IN OUT   UINTN    *SizeOfBuffer,
+  IN CONST VOID     *Buffer
+  )
+{
+  ASSERT (PatchVariable != NULL);
+  ASSERT (SizeOfPatchVariable != NULL);
+  ASSERT (SizeOfBuffer  != NULL);
+
+  if (*SizeOfBuffer > 0) {
+    ASSERT (Buffer != NULL);
+  }
+
+  if ((*SizeOfBuffer > MaximumDatumSize) ||
+      (*SizeOfBuffer == MAX_ADDRESS)) {
+    *SizeOfBuffer = MaximumDatumSize;
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  CopyMem (PatchVariable, Buffer, *SizeOfBuffer);
+  *SizeOfPatchVariable = *SizeOfBuffer;
+
+  return RETURN_SUCCESS;
+}
+
  /**
    Retrieve additional information associated with a PCD token.

    This includes information such as the type of value the TokenNumber is 
associated with as well as possible
    human readable name that is associated with the token.
diff --git a/MdePkg/Library/PeiPcdLib/PeiPcdLib.c 
b/MdePkg/Library/PeiPcdLib/PeiPcdLib.c
index 3d71396..e1eeb3a 100644
--- a/MdePkg/Library/PeiPcdLib/PeiPcdLib.c
+++ b/MdePkg/Library/PeiPcdLib/PeiPcdLib.c
@@ -1447,10 +1447,121 @@ LibPatchPcdSetPtrS (
    CopyMem (PatchVariable, Buffer, *SizeOfBuffer);

    return RETURN_SUCCESS;
  }

+
+/**
+  Sets a value and size of a patchable PCD entry that is type pointer.
+
+  Sets the PCD entry specified by PatchVariable to the value specified by 
Buffer
+  and SizeOfBuffer.  Buffer is returned.  If SizeOfBuffer is greater than
+  MaximumDatumSize, then set SizeOfBuffer to MaximumDatumSize and return
+  NULL to indicate that the set operation was not actually performed.
+  If SizeOfBuffer is set to MAX_ADDRESS, then SizeOfBuffer must be set to
+  MaximumDatumSize and NULL must be returned.
+
+  If PatchVariable is NULL, then ASSERT().
+  If SizeOfPatchVariable is NULL, then ASSERT().
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+
+  @param[out] PatchVariable     A pointer to the global variable in a module 
that is
+                                the target of the set operation.
+  @param[out] SizeOfPatchVariable A pointer to the size, in bytes, of 
PatchVariable.
+  @param[in] MaximumDatumSize   The maximum size allowed for the PCD entry 
specified by PatchVariable.
+  @param[in, out] SizeOfBuffer  A pointer to the size, in bytes, of Buffer.
+  @param[in] Buffer             A pointer to the buffer to used to set the 
target variable.
+
+  @return Return the pointer to the buffer been set.
+
+**/
+VOID *
+EFIAPI
+LibPatchPcdSetPtrAndSize (
+  OUT       VOID        *PatchVariable,
+  OUT       UINTN       *SizeOfPatchVariable,
+  IN        UINTN       MaximumDatumSize,
+  IN OUT    UINTN       *SizeOfBuffer,
+  IN CONST  VOID        *Buffer
+  )
+{
+  ASSERT (PatchVariable != NULL);
+  ASSERT (SizeOfPatchVariable != NULL);
+  ASSERT (SizeOfBuffer  != NULL);
+
+  if (*SizeOfBuffer > 0) {
+    ASSERT (Buffer != NULL);
+  }
+
+  if ((*SizeOfBuffer > MaximumDatumSize) ||
+      (*SizeOfBuffer == MAX_ADDRESS)) {
+    *SizeOfBuffer = MaximumDatumSize;
+    return NULL;
+  }
+
+  CopyMem (PatchVariable, Buffer, *SizeOfBuffer);
+  *SizeOfPatchVariable = *SizeOfBuffer;
+
+  return (VOID *) Buffer;
+}
+
+/**
+  Sets a value and size of a patchable PCD entry that is type pointer.
+
+  Sets the PCD entry specified by PatchVariable to the value specified
+  by Buffer and SizeOfBuffer. If SizeOfBuffer is greater than MaximumDatumSize,
+  then set SizeOfBuffer to MaximumDatumSize and return RETURN_INVALID_PARAMETER
+  to indicate that the set operation was not actually performed.
+  If SizeOfBuffer is set to MAX_ADDRESS, then SizeOfBuffer must be set to
+  MaximumDatumSize and RETURN_INVALID_PARAMETER must be returned.
+
+  If PatchVariable is NULL, then ASSERT().
+  If SizeOfPatchVariable is NULL, then ASSERT().
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+
+  @param[out] PatchVariable     A pointer to the global variable in a module 
that is
+                                the target of the set operation.
+  @param[out] SizeOfPatchVariable A pointer to the size, in bytes, of 
PatchVariable.
+  @param[in] MaximumDatumSize   The maximum size allowed for the PCD entry 
specified by PatchVariable.
+  @param[in, out] SizeOfBuffer  A pointer to the size, in bytes, of Buffer.
+  @param[in] Buffer             A pointer to the buffer to used to set the 
target variable.
+
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPatchPcdSetPtrAndSizeS (
+  OUT      VOID     *PatchVariable,
+  OUT      UINTN    *SizeOfPatchVariable,
+  IN       UINTN    MaximumDatumSize,
+  IN OUT   UINTN    *SizeOfBuffer,
+  IN CONST VOID     *Buffer
+  )
+{
+  ASSERT (PatchVariable != NULL);
+  ASSERT (SizeOfPatchVariable != NULL);
+  ASSERT (SizeOfBuffer  != NULL);
+
+  if (*SizeOfBuffer > 0) {
+    ASSERT (Buffer != NULL);
+  }
+
+  if ((*SizeOfBuffer > MaximumDatumSize) ||
+      (*SizeOfBuffer == MAX_ADDRESS)) {
+    *SizeOfBuffer = MaximumDatumSize;
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  CopyMem (PatchVariable, Buffer, *SizeOfBuffer);
+  *SizeOfPatchVariable = *SizeOfBuffer;
+
+  return RETURN_SUCCESS;
+}
+
  /**
    Retrieve additional information associated with a PCD token.

    This includes information such as the type of value the TokenNumber is 
associated with as well as possible
    human readable name that is associated with the token.


_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to