BaseTools: Add PcdValueCommon logic into C source CommonLib
authorLiming Gao <liming.gao@intel.com>
Thu, 23 Nov 2017 12:49:36 +0000 (20:49 +0800)
committerLiming Gao <liming.gao@intel.com>
Mon, 25 Dec 2017 03:05:45 +0000 (11:05 +0800)
PcdValueCommon is used to calculate structure pcd value.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
BaseTools/Source/C/Common/GNUmakefile
BaseTools/Source/C/Common/Makefile
BaseTools/Source/C/Common/PcdValueCommon.c [new file with mode: 0644]
BaseTools/Source/C/Common/PcdValueCommon.h [new file with mode: 0644]

index 5cbca9a..66bd3a6 100644 (file)
@@ -35,6 +35,7 @@ OBJECTS = \
   PeCoffLoaderEx.o \\r
   SimpleFileParsing.o \\r
   StringFuncs.o \\r
-  TianoCompress.o\r
+  TianoCompress.o \\r
+  PcdValueCommon.o\r
 \r
 include $(MAKEROOT)/Makefiles/lib.makefile\r
index 41119b1..beb94c7 100644 (file)
@@ -34,7 +34,8 @@ OBJECTS = \
   PeCoffLoaderEx.obj \\r
   SimpleFileParsing.obj \\r
   StringFuncs.obj \\r
-  TianoCompress.obj\r
+  TianoCompress.obj \\r
+  PcdValueCommon.obj\r
 \r
 !INCLUDE ..\Makefiles\ms.lib\r
 \r
diff --git a/BaseTools/Source/C/Common/PcdValueCommon.c b/BaseTools/Source/C/Common/PcdValueCommon.c
new file mode 100644 (file)
index 0000000..6ca0994
--- /dev/null
@@ -0,0 +1,790 @@
+/** @file\r
+This file contains the PcdValue structure definition.\r
+\r
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include "CommonLib.h"\r
+#include "PcdValueCommon.h"\r
+\r
+typedef enum {\r
+  PcdDataTypeBoolean,\r
+  PcdDataTypeUint8,\r
+  PcdDataTypeUint16,\r
+  PcdDataTypeUint32,\r
+  PcdDataTypeUint64,\r
+  PcdDataTypePointer\r
+} PCD_DATA_TYPE;\r
+\r
+typedef struct {\r
+  CHAR8          *SkuName;\r
+  CHAR8          *DefaultValueName;\r
+  CHAR8          *TokenSpaceGuidName;\r
+  CHAR8          *TokenName;\r
+  CHAR8          *DataType;\r
+  CHAR8          *Value;\r
+  PCD_DATA_TYPE  PcdDataType;\r
+} PCD_ENTRY;\r
+\r
+PCD_ENTRY  *PcdList;\r
+UINT32     PcdListLength;\r
+\r
+VOID\r
+STATIC\r
+RecordToken (\r
+  UINT8   *FileBuffer,\r
+  UINT32  PcdIndex,\r
+  UINT32  TokenIndex,\r
+  UINT32  TokenStart,\r
+  UINT32  TokenEnd\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Record new token information\r
+\r
+Arguments:\r
+\r
+  FileBuffer    File Buffer to be record\r
+  PcdIndex      Index of PCD in database\r
+  TokenIndex    Index of Token\r
+  TokenStart    Start of Token\r
+  TokenEnd      End of Token\r
+\r
+Returns:\r
+\r
+  None\r
+--*/\r
+{\r
+  CHAR8  *Token;\r
+\r
+  Token = malloc (TokenEnd - TokenStart + 1);\r
+  memcpy (Token, &FileBuffer[TokenStart], TokenEnd - TokenStart);\r
+  Token[TokenEnd - TokenStart] = 0;\r
+  switch (TokenIndex) {\r
+  case 0:\r
+    PcdList[PcdIndex].SkuName = Token;\r
+    break;\r
+  case 1:\r
+    PcdList[PcdIndex].DefaultValueName = Token;\r
+    break;\r
+  case 2:\r
+    PcdList[PcdIndex].TokenSpaceGuidName = Token;\r
+    break;\r
+  case 3:\r
+    PcdList[PcdIndex].TokenName = Token;\r
+    break;\r
+  case 4:\r
+    PcdList[PcdIndex].DataType = Token;\r
+    if (strcmp (Token, "BOOLEAN") == 0) {\r
+      PcdList[PcdIndex].PcdDataType = PcdDataTypeBoolean;\r
+    } else if (strcmp (Token, "UINT8") == 0) {\r
+      PcdList[PcdIndex].PcdDataType = PcdDataTypeUint8;\r
+    } else if (strcmp (Token, "UINT16") == 0) {\r
+      PcdList[PcdIndex].PcdDataType = PcdDataTypeUint16;\r
+    } else if (strcmp (Token, "UINT32") == 0) {\r
+      PcdList[PcdIndex].PcdDataType = PcdDataTypeUint32;\r
+    } else if (strcmp (Token, "UINT64") == 0) {\r
+      PcdList[PcdIndex].PcdDataType = PcdDataTypeUint64;\r
+    } else {\r
+      PcdList[PcdIndex].PcdDataType = PcdDataTypePointer;\r
+    }\r
+    break;\r
+  case 5:\r
+    PcdList[PcdIndex].Value = Token;\r
+    break;\r
+  }\r
+}\r
+\r
+int\r
+STATIC\r
+LookupPcdIndex (\r
+  CHAR8  *SkuName             OPTIONAL,\r
+  CHAR8  *DefaultValueName    OPTIONAL,\r
+  CHAR8  *TokenSpaceGuidName,\r
+  CHAR8  *TokenName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get PCD index in Pcd database\r
+\r
+Arguments:\r
+\r
+  SkuName               SkuName String\r
+  DefaultValueName      DefaultValueName String\r
+  TokenSpaceGuidName    TokenSpaceGuidName String\r
+  TokenName             TokenName String\r
+\r
+Returns:\r
+\r
+  Index of PCD in Pcd database\r
+--*/\r
+{\r
+  UINT32  Index;\r
+\r
+  if (SkuName == NULL) {\r
+    SkuName = "DEFAULT";\r
+  }\r
+  if (DefaultValueName == NULL) {\r
+    DefaultValueName = "DEFAULT";\r
+  }\r
+  for (Index = 0; Index < PcdListLength; Index++) {\r
+    if (strcmp(PcdList[Index].TokenSpaceGuidName, TokenSpaceGuidName) != 0) {\r
+      continue;\r
+    }\r
+    if (strcmp(PcdList[Index].TokenName, TokenName) != 0) {\r
+      continue;\r
+    }\r
+    if (strcmp(PcdList[Index].SkuName, SkuName) != 0) {\r
+      continue;\r
+    }\r
+    if (strcmp(PcdList[Index].DefaultValueName, DefaultValueName) != 0) {\r
+      continue;\r
+    }\r
+    return Index;\r
+  }\r
+  return -1;\r
+}\r
+\r
+UINT64\r
+__PcdGet (\r
+  CHAR8  *SkuName             OPTIONAL,\r
+  CHAR8  *DefaultValueName    OPTIONAL,\r
+  CHAR8  *TokenSpaceGuidName,\r
+  CHAR8  *TokenName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get PCD value\r
+\r
+Arguments:\r
+\r
+  SkuName               SkuName String\r
+  DefaultValueName      DefaultValueName String\r
+  TokenSpaceGuidName    TokenSpaceGuidName String\r
+  TokenName             TokenName String\r
+\r
+Returns:\r
+\r
+  PCD value\r
+--*/\r
+{\r
+  int    Index;\r
+  CHAR8  *End;\r
+\r
+  Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);\r
+  if (Index < 0) {\r
+    fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);\r
+    exit (EXIT_FAILURE);\r
+  }\r
+  switch (PcdList[Index].PcdDataType) {\r
+  case PcdDataTypeBoolean:\r
+  case PcdDataTypeUint8:\r
+  case PcdDataTypeUint16:\r
+  case PcdDataTypeUint32:\r
+    return (UINT64)strtoul(PcdList[Index].Value, &End, 16);\r
+    break;\r
+  case PcdDataTypeUint64:\r
+    return (UINT64)strtoul(PcdList[Index].Value, &End, 16);\r
+    break;\r
+  case PcdDataTypePointer:\r
+    fprintf (stderr, "PCD %s.%s.%s.%s is structure.  Use PcdGetPtr()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);\r
+    exit (EXIT_FAILURE);\r
+    break;\r
+  }\r
+  return 0;\r
+}\r
+\r
+VOID\r
+__PcdSet (\r
+  CHAR8   *SkuName             OPTIONAL,\r
+  CHAR8   *DefaultValueName    OPTIONAL,\r
+  CHAR8   *TokenSpaceGuidName,\r
+  CHAR8   *TokenName,\r
+  UINT64  Value\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set PCD value\r
+\r
+Arguments:\r
+\r
+  SkuName               SkuName String\r
+  DefaultValueName      DefaultValueName String\r
+  TokenSpaceGuidName    TokenSpaceGuidName String\r
+  TokenName             TokenName String\r
+  Value                 PCD value to be set\r
+\r
+Returns:\r
+\r
+  None\r
+--*/\r
+{\r
+  int    Index;\r
+\r
+  Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);\r
+  if (Index < 0) {\r
+    fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);\r
+    exit (EXIT_FAILURE);\r
+  }\r
+  free(PcdList[Index].Value);\r
+  PcdList[Index].Value = malloc(20);\r
+  switch (PcdList[Index].PcdDataType) {\r
+  case PcdDataTypeBoolean:\r
+    if (Value == 0) {\r
+      strcpy (PcdList[Index].Value, "0x00");\r
+    } else {\r
+      strcpy (PcdList[Index].Value, "0x01");\r
+    }\r
+    break;\r
+  case PcdDataTypeUint8:\r
+    sprintf(PcdList[Index].Value, "0x%02x", (UINT8)(Value & 0xff));\r
+    break;\r
+  case PcdDataTypeUint16:\r
+    sprintf(PcdList[Index].Value, "0x%04x", (UINT16)(Value & 0xffff));\r
+    break;\r
+  case PcdDataTypeUint32:\r
+    sprintf(PcdList[Index].Value, "0x%08x", (UINT32)(Value & 0xffffffff));\r
+    break;\r
+  case PcdDataTypeUint64:\r
+#ifdef __GNUC__\r
+    sprintf(PcdList[Index].Value, "0x%016lx", Value);\r
+#else\r
+    sprintf(PcdList[Index].Value, "0x%016llx", Value);\r
+#endif\r
+    break;\r
+  case PcdDataTypePointer:\r
+    fprintf (stderr, "PCD %s.%s.%s.%s is structure.  Use PcdSetPtr()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);\r
+    exit (EXIT_FAILURE);\r
+    break;\r
+  }\r
+}\r
+\r
+VOID *\r
+__PcdGetPtr (\r
+  CHAR8   *SkuName             OPTIONAL,\r
+  CHAR8   *DefaultValueName    OPTIONAL,\r
+  CHAR8   *TokenSpaceGuidName,\r
+  CHAR8   *TokenName,\r
+  UINT32  *Size\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get PCD value buffer\r
+\r
+Arguments:\r
+\r
+  SkuName               SkuName String\r
+  DefaultValueName      DefaultValueName String\r
+  TokenSpaceGuidName    TokenSpaceGuidName String\r
+  TokenName             TokenName String\r
+  Size                  Size of PCD value buffer\r
+\r
+Returns:\r
+\r
+  PCD value buffer\r
+--*/\r
+{\r
+  int    Index;\r
+  CHAR8   *Value;\r
+  UINT8   *Buffer;\r
+  CHAR8   *End;\r
+  UINT8   Byte;\r
+\r
+  Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);\r
+  if (Index < 0) {\r
+    fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);\r
+    exit (EXIT_FAILURE);\r
+  }\r
+  switch (PcdList[Index].PcdDataType) {\r
+  case PcdDataTypeBoolean:\r
+  case PcdDataTypeUint8:\r
+  case PcdDataTypeUint16:\r
+  case PcdDataTypeUint32:\r
+  case PcdDataTypeUint64:\r
+    fprintf (stderr, "PCD %s.%s.%s.%s is a value.  Use PcdGet()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);\r
+    exit (EXIT_FAILURE);\r
+    break;\r
+  case PcdDataTypePointer:\r
+    Value = &PcdList[Index].Value[1];\r
+    printf ("Value = %s\n", PcdList[Index].Value);\r
+    for (*Size = 0, Byte = (UINT8) strtoul(Value, &End, 16); Value != End; Byte = (UINT8) strtoul(Value, &End, 16), *Size = *Size + 1) {\r
+      printf("%x\n", Byte);\r
+      Value = End + 1;\r
+    }\r
+    Buffer = malloc(*Size);\r
+    Value = &PcdList[Index].Value[1];\r
+    for (*Size = 0, Buffer[*Size] = (UINT8) strtoul(Value, &End, 16); Value != End; *Size = *Size + 1, Buffer[*Size] = (UINT8) strtoul(Value, &End, 16)) {\r
+      Value = End + 1;\r
+    }\r
+    return Buffer;\r
+  }\r
+  *Size = 0;\r
+  return 0;\r
+}\r
+\r
+VOID\r
+__PcdSetPtr (\r
+  CHAR8   *SkuName             OPTIONAL,\r
+  CHAR8   *DefaultValueName    OPTIONAL,\r
+  CHAR8   *TokenSpaceGuidName,\r
+  CHAR8   *TokenName,\r
+  UINT32  Size,\r
+  UINT8   *Value\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set PCD value buffer\r
+\r
+Arguments:\r
+\r
+  SkuName               SkuName String\r
+  DefaultValueName      DefaultValueName String\r
+  TokenSpaceGuidName    TokenSpaceGuidName String\r
+  TokenName             TokenName String\r
+  Size                  Size of PCD value\r
+  Value                 Pointer to the updated PCD value buffer\r
+\r
+Returns:\r
+\r
+  None\r
+--*/\r
+{\r
+  int    Index;\r
+  UINT32  ValueIndex;\r
+\r
+  Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);\r
+  if (Index < 0) {\r
+    fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);\r
+    exit (EXIT_FAILURE);\r
+  }\r
+  switch (PcdList[Index].PcdDataType) {\r
+  case PcdDataTypeBoolean:\r
+  case PcdDataTypeUint8:\r
+  case PcdDataTypeUint16:\r
+  case PcdDataTypeUint32:\r
+  case PcdDataTypeUint64:\r
+    fprintf (stderr, "PCD %s.%s.%s.%s is a value.  Use PcdGet()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);\r
+    exit (EXIT_FAILURE);\r
+    break;\r
+  case PcdDataTypePointer:\r
+    free(PcdList[Index].Value);\r
+    PcdList[Index].Value = malloc(Size * 5 + 3);\r
+    PcdList[Index].Value[0] = '{';\r
+    for (ValueIndex = 0; ValueIndex < Size; ValueIndex++) {\r
+      printf("Value[%d] = %02x\n", ValueIndex, Value[ValueIndex]);\r
+      sprintf(&PcdList[Index].Value[1 + ValueIndex * 5], "0x%02x,", Value[ValueIndex]);\r
+    }\r
+    PcdList[Index].Value[1 + Size * 5 - 1] = '}';\r
+    PcdList[Index].Value[1 + Size * 5    ] = 0;\r
+    break;\r
+  }\r
+}\r
+\r
+VOID\r
+STATIC\r
+ReadInputFile (\r
+  CHAR8   *InputFileName,\r
+  UINT8   **FileBuffer,\r
+  UINT32  *FileSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Read the file buffer from the input file.\r
+\r
+Arguments:\r
+\r
+  InputFileName Point to the input file name.\r
+  FileBuffer    Point to the input file buffer.\r
+  FileSize      Size of the file buffer.\r
+\r
+Returns:\r
+\r
+  None\r
+--*/\r
+{\r
+  FILE    *InputFile;\r
+  UINT32  BytesRead;\r
+\r
+  //\r
+  // Open Input file and read file data.\r
+  //\r
+  InputFile = fopen (InputFileName, "rb");\r
+  if (InputFile == NULL) {\r
+    fprintf (stderr, "Error opening file %s\n", InputFileName);\r
+    exit (EXIT_FAILURE);\r
+  }\r
+\r
+  //\r
+  // Go to the end so that we can determine the file size\r
+  //\r
+  if (fseek (InputFile, 0, SEEK_END)) {\r
+    fprintf (stderr, "Error reading input file %s\n", InputFileName);\r
+    fclose (InputFile);\r
+    exit (EXIT_FAILURE);\r
+  }\r
+\r
+  //\r
+  // Get the file size\r
+  //\r
+  *FileSize = ftell (InputFile);\r
+  if (*FileSize == -1) {\r
+    fprintf (stderr, "Error parsing the input file %s\n", InputFileName);\r
+    fclose (InputFile);\r
+    exit (EXIT_FAILURE);\r
+  }\r
+\r
+  //\r
+  // Allocate a buffer\r
+  //\r
+  *FileBuffer = malloc (*FileSize);\r
+  if (*FileBuffer == NULL) {\r
+    fprintf (stderr, "Can not allocate buffer for input input file %s\n", InputFileName);\r
+    fclose (InputFile);\r
+    exit (EXIT_FAILURE);\r
+  }\r
+\r
+  //\r
+  // Reset to the beginning of the file\r
+  //\r
+  if (fseek (InputFile, 0, SEEK_SET)) {\r
+    fprintf (stderr, "Error reading the input file %s\n", InputFileName);\r
+    fclose (InputFile);\r
+    free (*FileBuffer);\r
+    exit (EXIT_FAILURE);\r
+  }\r
+\r
+  //\r
+  // Read all of the file contents.\r
+  //\r
+  BytesRead = fread (*FileBuffer, sizeof (UINT8), *FileSize, InputFile);\r
+  if (BytesRead != *FileSize * sizeof (UINT8)) {\r
+    fprintf (stderr, "Error reading the input file %s\n", InputFileName);\r
+    fclose (InputFile);\r
+    free (*FileBuffer);\r
+    exit (EXIT_FAILURE);\r
+  }\r
+\r
+  //\r
+  // Close the file\r
+  //\r
+  fclose (InputFile);\r
+}\r
+\r
+VOID\r
+STATIC\r
+ParseFile (\r
+  UINT8   *FileBuffer,\r
+  UINT32  FileSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Read the initial PCD value from the input file buffer.\r
+\r
+Arguments:\r
+\r
+  FileBuffer  Point to the input file buffer.\r
+  FileSize    Size of the file buffer.\r
+\r
+Returns:\r
+\r
+  None\r
+--*/\r
+{\r
+  UINT32  Index;\r
+  UINT32  NumLines;\r
+  UINT32  TokenIndex;\r
+  UINT32  TokenStart;\r
+\r
+  for (Index = 0, NumLines = 0; Index < FileSize; Index++) {\r
+    if (FileBuffer[Index] == '\n') {\r
+      NumLines++;\r
+    }\r
+  }\r
+  PcdList = malloc((NumLines + 1) * sizeof(PcdList[0]));\r
+\r
+  for (Index = 0, TokenIndex = 0, PcdListLength = 0, TokenStart = 0; Index < FileSize; Index++) {\r
+    if (FileBuffer[Index] == ' ') {\r
+      continue;\r
+    }\r
+    if (FileBuffer[Index] == '|' || FileBuffer[Index] == '.' || FileBuffer[Index] == '\n' || FileBuffer[Index] == '\r') {\r
+      RecordToken (FileBuffer, PcdListLength, TokenIndex, TokenStart, Index);\r
+      if (FileBuffer[Index] == '\n' || FileBuffer[Index] == '\r') {\r
+        if (TokenIndex != 0) {\r
+          PcdListLength++;\r
+          TokenIndex = 0;\r
+        }\r
+      } else {\r
+        TokenIndex++;\r
+      }\r
+      TokenStart = Index + 1;\r
+      continue;\r
+    }\r
+  }\r
+  if (Index > TokenStart) {\r
+    RecordToken (FileBuffer, PcdListLength, TokenIndex, TokenStart, Index);\r
+    if (TokenIndex != 0) {\r
+      PcdListLength++;\r
+    }\r
+  }\r
+}\r
+\r
+VOID\r
+STATIC\r
+WriteOutputFile (\r
+  CHAR8   *OutputFileName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Write the updated PCD value into the output file name.\r
+\r
+Arguments:\r
+\r
+  OutputFileName  Point to the output file name.\r
+\r
+Returns:\r
+\r
+  None\r
+--*/\r
+{\r
+  FILE    *OutputFile;\r
+  UINT32  Index;\r
+\r
+  //\r
+  // Open output file\r
+  //\r
+  OutputFile = fopen (OutputFileName, "wb");\r
+  if (OutputFile == NULL) {\r
+    fprintf (stderr, "Error opening file %s\n", OutputFileName);\r
+    exit (EXIT_FAILURE);\r
+  }\r
+\r
+  for (Index = 0; Index < PcdListLength; Index++) {\r
+    fprintf (\r
+      OutputFile,\r
+      "%s.%s.%s.%s|%s|%s\n",\r
+      PcdList[Index].SkuName,\r
+      PcdList[Index].DefaultValueName,\r
+      PcdList[Index].TokenSpaceGuidName,\r
+      PcdList[Index].TokenName,\r
+      PcdList[Index].DataType,\r
+      PcdList[Index].Value\r
+      );\r
+  }\r
+\r
+  //\r
+  // Done, write output file.\r
+  //\r
+  if (OutputFile != NULL) {\r
+    fclose (OutputFile);\r
+  }\r
+}\r
+\r
+VOID\r
+STATIC\r
+Usage (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Displays the utility usage syntax to STDOUT\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns:\r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  fprintf (stdout, "Usage: -i <input_file> -o <output_file>\n\n");\r
+  fprintf (stdout, "optional arguments:\n");\r
+  fprintf (stdout, "  -h, --help            Show this help message and exit\n");\r
+  fprintf (stdout, "  -i INPUT_FILENAME, --input INPUT_FILENAME\n\\r
+                        PCD Database Input file name\n");\r
+  fprintf (stdout, "  -o OUTPUT_FILENAME, --output OUTPUT_FILENAME\n\\r
+                        PCD Database Output file name\n");\r
+}\r
+\r
+VOID\r
+STATIC\r
+ParseArguments (\r
+  int    argc,\r
+  char   *argv[],\r
+  CHAR8  **InputFileName,\r
+  CHAR8  **OutputFileName\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Parse the input parameters to get the input/output file name.\r
+\r
+Arguments:\r
+\r
+  argc            Number of command line parameters.\r
+  argv            Array of pointers to parameter strings.\r
+  InputFileName   Point to the input file name.\r
+  OutputFileName  Point to the output file name.\r
+\r
+Returns:\r
+\r
+  None\r
+--*/\r
+{\r
+  if (argc == 1) {\r
+    fprintf (stderr, "Missing options\n");\r
+    exit (EXIT_FAILURE);\r
+  }\r
+\r
+  //\r
+  // Parse command line\r
+  //\r
+  argc--;\r
+  argv++;\r
+\r
+  if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {\r
+    Usage ();\r
+    exit (EXIT_SUCCESS);\r
+  }\r
+\r
+  while (argc > 0) {\r
+    if ((stricmp (argv[0], "-i") == 0) || (stricmp (argv[0], "--input") == 0)) {\r
+      if (argv[1] == NULL || argv[1][0] == '-') {\r
+        fprintf (stderr, "Invalid option value.  Input File name is missing for -i option\n");\r
+        exit (EXIT_FAILURE);\r
+      }\r
+      *InputFileName = argv[1];\r
+      argc -= 2;\r
+      argv += 2;\r
+      continue;\r
+    }\r
+\r
+    if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--output") == 0)) {\r
+      if (argv[1] == NULL || argv[1][0] == '-') {\r
+        fprintf (stderr, "Invalid option value.  Output File name is missing for -i option\n");\r
+        exit (EXIT_FAILURE);\r
+      }\r
+      *OutputFileName = argv[1];\r
+      argc -= 2;\r
+      argv += 2;\r
+      continue;\r
+    }\r
+\r
+    if (argv[0][0] == '-') {\r
+      fprintf (stderr, "Unknown option %s\n", argv[0]);\r
+      exit (EXIT_FAILURE);\r
+    }\r
+    argc --;\r
+    argv ++;\r
+  }\r
+\r
+  //\r
+  // Check Input paramters\r
+  //\r
+  if (*InputFileName == NULL) {\r
+    fprintf (stderr, "Missing option.  Input files is not specified\n");\r
+    exit (EXIT_FAILURE);\r
+  } else {\r
+    printf ("Input file name is %s\n", *InputFileName);\r
+  }\r
+\r
+  if (*OutputFileName == NULL) {\r
+    fprintf (stderr, "Missing option.  Output file is not specified\n");\r
+    exit (EXIT_FAILURE);\r
+  } else {\r
+    printf ("Output file name is %s\n", *OutputFileName);\r
+  }\r
+}\r
+\r
+int\r
+PcdValueMain (\r
+  int   argc,\r
+  char  *argv[]\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Main function updates PCD values.\r
+\r
+Arguments:\r
+\r
+  argc            Number of command line parameters.\r
+  argv            Array of pointers to parameter strings.\r
+\r
+Returns:\r
+  EXIT_SUCCESS\r
+--*/\r
+{\r
+  CHAR8   *InputFileName;\r
+  CHAR8   *OutputFileName;\r
+  UINT8   *FileBuffer;\r
+  UINT32  FileSize;\r
+\r
+  printf ("PCD tool start.\n");\r
+  InputFileName = NULL;\r
+  OutputFileName = NULL;\r
+\r
+  //\r
+  // Parse the input arguments\r
+  //\r
+  ParseArguments (argc, argv, &InputFileName, &OutputFileName);\r
+\r
+  //\r
+  // Open Input file and read file data.\r
+  //\r
+  ReadInputFile (InputFileName, &FileBuffer, &FileSize);\r
+\r
+  //\r
+  // Read the initial Pcd value\r
+  //\r
+  ParseFile (FileBuffer, FileSize);\r
+\r
+  //\r
+  // Customize PCD values in the PCD Database\r
+  //\r
+  PcdEntryPoint ();\r
+\r
+  //\r
+  // Save the updated PCD value\r
+  //\r
+  WriteOutputFile (OutputFileName);\r
+\r
+  printf ("PCD tool done.\n");\r
+\r
+  exit (EXIT_SUCCESS);\r
+}\r
diff --git a/BaseTools/Source/C/Common/PcdValueCommon.h b/BaseTools/Source/C/Common/PcdValueCommon.h
new file mode 100644 (file)
index 0000000..3922428
--- /dev/null
@@ -0,0 +1,184 @@
+/** @file\r
+Header file for PcdValue structure definition.\r
+\r
+Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _PCD_VALUE_COMMON_H\r
+#define _PCD_VALUE_COMMON_H\r
+\r
+#include <Common/UefiBaseTypes.h>\r
+#include <Common/UefiInternalFormRepresentation.h>\r
+\r
+#define __FIELD_SIZE(TYPE, Field) (sizeof((TYPE *)0)->Field)\r
+#define __ARRAY_ELEMENT_SIZE(TYPE, Field) (sizeof((TYPE *)0)->Field[0])\r
+#define __OFFSET_OF(TYPE, Field) ((UINT32) &(((TYPE *)0)->Field))\r
+#define __FLEXIBLE_SIZE(Size, TYPE, Field, MaxIndex)   if (__FIELD_SIZE(TYPE, Field) == 0) Size = MAX((__OFFSET_OF(TYPE, Field) + __ARRAY_ELEMENT_SIZE(TYPE, Field) * (MaxIndex)), Size)\r
+\r
+VOID\r
+PcdEntryPoint (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Main function updates PCD values. It is auto generated by Build\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns:\r
+  None\r
+--*/\r
+;\r
+\r
+int\r
+PcdValueMain (\r
+  int   argc,\r
+  char  *argv[]\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Main function updates PCD values.\r
+\r
+Arguments:\r
+\r
+  argc            Number of command line parameters.\r
+  argv            Array of pointers to parameter strings.\r
+\r
+Returns:\r
+  EXIT_SUCCESS\r
+--*/\r
+;\r
+\r
+VOID\r
+__PcdSet (\r
+  CHAR8   *SkuName             OPTIONAL,\r
+  CHAR8   *DefaultValueName    OPTIONAL,\r
+  CHAR8   *TokenSpaceGuidName,\r
+  CHAR8   *TokenName,\r
+  UINT64  Value\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get PCD value\r
+\r
+Arguments:\r
+\r
+  SkuName               SkuName String\r
+  DefaultValueName      DefaultValueName String\r
+  TokenSpaceGuidName    TokenSpaceGuidName String\r
+  TokenName             TokenName String\r
+\r
+Returns:\r
+\r
+  PCD value\r
+--*/\r
+;\r
+\r
+VOID\r
+__PcdSet (\r
+  CHAR8   *SkuName             OPTIONAL,\r
+  CHAR8   *DefaultValueName    OPTIONAL,\r
+  CHAR8   *TokenSpaceGuidName,\r
+  CHAR8   *TokenName,\r
+  UINT64  Value\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set PCD value\r
+\r
+Arguments:\r
+\r
+  SkuName               SkuName String\r
+  DefaultValueName      DefaultValueName String\r
+  TokenSpaceGuidName    TokenSpaceGuidName String\r
+  TokenName             TokenName String\r
+  Value                 PCD value to be set\r
+\r
+Returns:\r
+\r
+  None\r
+--*/\r
+;\r
+\r
+VOID *\r
+__PcdGetPtr (\r
+  CHAR8   *SkuName             OPTIONAL,\r
+  CHAR8   *DefaultValueName    OPTIONAL,\r
+  CHAR8   *TokenSpaceGuidName,\r
+  CHAR8   *TokenName,\r
+  UINT32  *Size\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get PCD value buffer\r
+\r
+Arguments:\r
+\r
+  SkuName               SkuName String\r
+  DefaultValueName      DefaultValueName String\r
+  TokenSpaceGuidName    TokenSpaceGuidName String\r
+  TokenName             TokenName String\r
+  Size                  Size of PCD value buffer\r
+\r
+Returns:\r
+\r
+  PCD value buffer\r
+--*/\r
+;\r
+\r
+VOID\r
+__PcdSetPtr (\r
+  CHAR8   *SkuName             OPTIONAL,\r
+  CHAR8   *DefaultValueName    OPTIONAL,\r
+  CHAR8   *TokenSpaceGuidName,\r
+  CHAR8   *TokenName,\r
+  UINT32  Size,\r
+  UINT8   *Value\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set PCD value buffer\r
+\r
+Arguments:\r
+\r
+  SkuName               SkuName String\r
+  DefaultValueName      DefaultValueName String\r
+  TokenSpaceGuidName    TokenSpaceGuidName String\r
+  TokenName             TokenName String\r
+  Size                  Size of PCD value\r
+  Value                 Pointer to the updated PCD value buffer\r
+\r
+Returns:\r
+\r
+  None\r
+--*/\r
+;\r
+\r
+#define PcdGet(A, B, C, D)  __PcdGet(#A, #B, #C, #D)\r
+#define PcdSet(A, B, C, D, Value)  __PcdSet(#A, #B, #C, #D, Value)\r
+#define PcdGetPtr(A, B, C, D, Size)  __PcdGetPtr(#A, #B, #C, #D, Size)\r
+#define PcdSetPtr(A, B, C, D, Size, Value)  __PcdSetPtr(#A, #B, #C, #D, Size, Value)\r
+\r
+#endif\r