* [RFC 2/3] BaseTools: Add PcdValueCommon logic into CommonLib
2017-04-11 15:16 [RFC 0/3] Structure PCD value assignment in DEC/DSC Liming Gao
2017-04-11 15:16 ` [RFC 1/3] BaseTools: Update Makefile to work at absolute path Liming Gao
@ 2017-04-11 15:16 ` Liming Gao
2017-04-11 15:16 ` [RFC 3/3] TestPkg: Show Structure PCD value assignment Liming Gao
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Liming Gao @ 2017-04-11 15:16 UTC (permalink / raw)
To: edk2-devel
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Liming Gao <liming.gao@intel.com>
---
BaseTools/Source/C/Common/GNUmakefile | 3 +-
BaseTools/Source/C/Common/Makefile | 3 +-
BaseTools/Source/C/Common/PcdValueCommon.c | 601 +++++++++++++++++++++++++++++
BaseTools/Source/C/Common/PcdValueCommon.h | 78 ++++
BaseTools/Source/C/Makefiles/lib.makefile | 2 +
5 files changed, 685 insertions(+), 2 deletions(-)
create mode 100644 BaseTools/Source/C/Common/PcdValueCommon.c
create mode 100644 BaseTools/Source/C/Common/PcdValueCommon.h
diff --git a/BaseTools/Source/C/Common/GNUmakefile b/BaseTools/Source/C/Common/GNUmakefile
index a193557..574d556 100644
--- a/BaseTools/Source/C/Common/GNUmakefile
+++ b/BaseTools/Source/C/Common/GNUmakefile
@@ -35,6 +35,7 @@ OBJECTS = \
PeCoffLoaderEx.o \
SimpleFileParsing.o \
StringFuncs.o \
- TianoCompress.o
+ TianoCompress.o \
+ PcdValueCommon.o
include $(MAKEROOT)/Makefiles/lib.makefile
diff --git a/BaseTools/Source/C/Common/Makefile b/BaseTools/Source/C/Common/Makefile
index 41119b1..beb94c7 100644
--- a/BaseTools/Source/C/Common/Makefile
+++ b/BaseTools/Source/C/Common/Makefile
@@ -34,7 +34,8 @@ OBJECTS = \
PeCoffLoaderEx.obj \
SimpleFileParsing.obj \
StringFuncs.obj \
- TianoCompress.obj
+ TianoCompress.obj \
+ PcdValueCommon.obj
!INCLUDE ..\Makefiles\ms.lib
diff --git a/BaseTools/Source/C/Common/PcdValueCommon.c b/BaseTools/Source/C/Common/PcdValueCommon.c
new file mode 100644
index 0000000..05b1328
--- /dev/null
+++ b/BaseTools/Source/C/Common/PcdValueCommon.c
@@ -0,0 +1,601 @@
+/** @file
+This file contains the PcdValue structure definition.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "CommonLib.h"
+#include "PcdValueCommon.h"
+
+typedef enum {
+ PcdDataTypeBoolean,
+ PcdDataTypeUint8,
+ PcdDataTypeUint16,
+ PcdDataTypeUint32,
+ PcdDataTypeUint64,
+ PcdDataTypePointer
+} PCD_DATA_TYPE;
+
+typedef struct {
+ CHAR8 *SkuName;
+ CHAR8 *DefaultValueName;
+ CHAR8 *TokenSpaceGuidName;
+ CHAR8 *TokenName;
+ CHAR8 *DataType;
+ CHAR8 *Value;
+ PCD_DATA_TYPE PcdDataType;
+} PCD_ENTRY;
+
+PCD_ENTRY *PcdList;
+UINT32 PcdListLength;
+
+VOID
+STATIC
+RecordToken (
+ UINT8 *FileBuffer,
+ UINT32 PcdIndex,
+ UINT32 TokenIndex,
+ UINT32 TokenStart,
+ UINT32 TokenEnd
+ )
+{
+ UINT8 *Token;
+
+ Token = malloc (TokenEnd - TokenStart + 1);
+ memcpy (Token, &FileBuffer[TokenStart], TokenEnd - TokenStart);
+ Token[TokenEnd - TokenStart] = 0;
+ switch (TokenIndex) {
+ case 0:
+ PcdList[PcdIndex].SkuName = Token;
+ break;
+ case 1:
+ PcdList[PcdIndex].DefaultValueName = Token;
+ break;
+ case 2:
+ PcdList[PcdIndex].TokenSpaceGuidName = Token;
+ break;
+ case 3:
+ PcdList[PcdIndex].TokenName = Token;
+ break;
+ case 4:
+ PcdList[PcdIndex].DataType = Token;
+ if (strcmp (Token, "BOOLEAN") == 0) {
+ PcdList[PcdIndex].PcdDataType = PcdDataTypeBoolean;
+ } else if (strcmp (Token, "UINT8") == 0) {
+ PcdList[PcdIndex].PcdDataType = PcdDataTypeUint8;
+ } else if (strcmp (Token, "UINT16") == 0) {
+ PcdList[PcdIndex].PcdDataType = PcdDataTypeUint16;
+ } else if (strcmp (Token, "UINT32") == 0) {
+ PcdList[PcdIndex].PcdDataType = PcdDataTypeUint32;
+ } else if (strcmp (Token, "UINT64") == 0) {
+ PcdList[PcdIndex].PcdDataType = PcdDataTypeUint64;
+ } else {
+ PcdList[PcdIndex].PcdDataType = PcdDataTypePointer;
+ }
+ break;
+ case 5:
+ PcdList[PcdIndex].Value = Token;
+ break;
+ }
+}
+
+int
+STATIC
+LookupPcdIndex (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName
+ )
+{
+ UINT32 Index;
+
+ if (SkuName == NULL) {
+ SkuName = "DEFAULT";
+ }
+ if (DefaultValueName == NULL) {
+ DefaultValueName = "DEFAULT";
+ }
+ for (Index = 0; Index < PcdListLength; Index++) {
+ if (strcmp(PcdList[Index].TokenSpaceGuidName, TokenSpaceGuidName) != 0) {
+ continue;
+ }
+ if (strcmp(PcdList[Index].TokenName, TokenName) != 0) {
+ continue;
+ }
+ if (strcmp(PcdList[Index].SkuName, SkuName) != 0) {
+ continue;
+ }
+ if (strcmp(PcdList[Index].DefaultValueName, DefaultValueName) != 0) {
+ continue;
+ }
+ return Index;
+ }
+ return -1;
+}
+
+UINT64
+__PcdGet (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName
+ )
+{
+ int Index;
+ UINT8 *End;
+
+ Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ if (Index < 0) {
+ fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ exit (EXIT_FAILURE);
+ }
+ switch (PcdList[Index].PcdDataType) {
+ case PcdDataTypeBoolean:
+ case PcdDataTypeUint8:
+ case PcdDataTypeUint16:
+ case PcdDataTypeUint32:
+ return (UINT64)strtoul(PcdList[Index].Value, &End, 16);
+ break;
+ case PcdDataTypeUint64:
+ return (UINT64)strtoull(PcdList[Index].Value, &End, 16);
+ break;
+ case PcdDataTypePointer:
+ fprintf (stderr, "PCD %s.%s.%s.%s is structure. Use PcdGetPtr()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ exit (EXIT_FAILURE);
+ break;
+ }
+ return 0;
+}
+
+VOID
+__PcdSet (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName,
+ UINT64 Value
+ )
+{
+ int Index;
+
+ Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ if (Index < 0) {
+ fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ exit (EXIT_FAILURE);
+ }
+ free(PcdList[Index].Value);
+ PcdList[Index].Value = malloc(20);
+ switch (PcdList[Index].PcdDataType) {
+ case PcdDataTypeBoolean:
+ if (Value == 0) {
+ strcpy (PcdList[Index].Value, "0x00");
+ } else {
+ strcpy (PcdList[Index].Value, "0x01");
+ }
+ break;
+ case PcdDataTypeUint8:
+ sprintf(PcdList[Index].Value, "0x%02x", (UINT8)(Value & 0xff));
+ break;
+ case PcdDataTypeUint16:
+ sprintf(PcdList[Index].Value, "0x%04x", (UINT16)(Value & 0xffff));
+ break;
+ case PcdDataTypeUint32:
+ sprintf(PcdList[Index].Value, "0x%08x", (UINT32)(Value & 0xffffffff));
+ break;
+ case PcdDataTypeUint64:
+ sprintf(PcdList[Index].Value, "0x%016llx", Value);
+ break;
+ case PcdDataTypePointer:
+ fprintf (stderr, "PCD %s.%s.%s.%s is structure. Use PcdSetPtr()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ exit (EXIT_FAILURE);
+ break;
+ }
+}
+
+VOID *
+__PcdGetPtr (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName,
+ UINT32 *Size
+ )
+{
+ int Index;
+ UINT8 *Value;
+ UINT8 *Buffer;
+ UINT8 *End;
+ UINT8 Byte;
+
+ Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ if (Index < 0) {
+ fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ exit (EXIT_FAILURE);
+ }
+ switch (PcdList[Index].PcdDataType) {
+ case PcdDataTypeBoolean:
+ case PcdDataTypeUint8:
+ case PcdDataTypeUint16:
+ case PcdDataTypeUint32:
+ case PcdDataTypeUint64:
+ fprintf (stderr, "PCD %s.%s.%s.%s is a value. Use PcdGet()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ exit (EXIT_FAILURE);
+ break;
+ case PcdDataTypePointer:
+ Value = &PcdList[Index].Value[1];
+ printf ("Value = %s\n", PcdList[Index].Value);
+ for (*Size = 0, Byte = (UINT8) strtoul(Value, &End, 16); Value != End; Byte = (UINT8) strtoul(Value, &End, 16), *Size = *Size + 1) {
+ printf("%x\n", Byte);
+ Value = End + 1;
+ }
+ Buffer = malloc(*Size);
+ Value = &PcdList[Index].Value[1];
+ for (*Size = 0, Buffer[*Size] = (UINT8) strtoul(Value, &End, 16); Value != End; Buffer[*Size] = (UINT8) strtoul(Value, &End, 16), *Size = *Size + 1) {
+ Value = End + 1;
+ }
+ return Buffer;
+ }
+ *Size = 0;
+ return 0;
+}
+
+VOID
+__PcdSetPtr (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName,
+ UINT32 Size,
+ UINT8 *Value
+ )
+{
+ int Index;
+ UINT32 ValueIndex;
+
+ Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ if (Index < 0) {
+ fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ exit (EXIT_FAILURE);
+ }
+ switch (PcdList[Index].PcdDataType) {
+ case PcdDataTypeBoolean:
+ case PcdDataTypeUint8:
+ case PcdDataTypeUint16:
+ case PcdDataTypeUint32:
+ case PcdDataTypeUint64:
+ fprintf (stderr, "PCD %s.%s.%s.%s is a value. Use PcdGet()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
+ exit (EXIT_FAILURE);
+ break;
+ case PcdDataTypePointer:
+ free(PcdList[Index].Value);
+ PcdList[Index].Value = malloc(Size * 5 + 3);
+ PcdList[Index].Value[0] = '{';
+ for (ValueIndex = 0; ValueIndex < Size; ValueIndex++) {
+ printf("Value[%d] = %02x\n", ValueIndex, Value[ValueIndex]);
+ sprintf(&PcdList[Index].Value[1 + ValueIndex * 5], "0x%02x,", Value[ValueIndex]);
+ }
+ PcdList[Index].Value[1 + Size * 5 - 1] = '}';
+ PcdList[Index].Value[1 + Size * 5 ] = 0;
+ break;
+ }
+}
+
+VOID
+STATIC
+ReadInputFile (
+ CHAR8 *InputFileName,
+ UINT8 **FileBuffer,
+ UINT32 *FileSize
+ )
+{
+ FILE *InputFile;
+ UINT32 BytesRead;
+
+ //
+ // Open Input file and read file data.
+ //
+ InputFile = fopen (InputFileName, "rb");
+ if (InputFile == NULL) {
+ fprintf (stderr, "Error opening file %s\n", InputFileName);
+ exit (EXIT_FAILURE);
+ }
+
+ //
+ // Go to the end so that we can determine the file size
+ //
+ if (fseek (InputFile, 0, SEEK_END)) {
+ fprintf (stderr, "Error reading input file %s\n", InputFileName);
+ fclose (InputFile);
+ exit (EXIT_FAILURE);
+ }
+
+ //
+ // Get the file size
+ //
+ *FileSize = ftell (InputFile);
+ if (*FileSize == -1) {
+ fprintf (stderr, "Error parsing the input file %s\n", InputFileName);
+ fclose (InputFile);
+ exit (EXIT_FAILURE);
+ }
+
+ //
+ // Allocate a buffer
+ //
+ *FileBuffer = malloc (*FileSize);
+ if (*FileBuffer == NULL) {
+ fprintf (stderr, "Can not allocate buffer for input input file %s\n", InputFileName);
+ fclose (InputFile);
+ exit (EXIT_FAILURE);
+ }
+
+ //
+ // Reset to the beginning of the file
+ //
+ if (fseek (InputFile, 0, SEEK_SET)) {
+ fprintf (stderr, "Error reading the input file %s\n", InputFileName);
+ fclose (InputFile);
+ free (*FileBuffer);
+ exit (EXIT_FAILURE);
+ }
+
+ //
+ // Read all of the file contents.
+ //
+ BytesRead = fread (*FileBuffer, sizeof (UINT8), *FileSize, InputFile);
+ if (BytesRead != *FileSize * sizeof (UINT8)) {
+ fprintf (stderr, "Error reading the input file %s\n", InputFileName);
+ fclose (InputFile);
+ free (*FileBuffer);
+ exit (EXIT_FAILURE);
+ }
+
+ //
+ // Close the file
+ //
+ fclose (InputFile);
+}
+
+VOID
+STATIC
+ParseFile (
+ UINT8 *FileBuffer,
+ UINT32 FileSize
+ )
+{
+ UINT32 Index;
+ UINT32 NumLines;
+ UINT32 TokenIndex;
+ UINT32 TokenStart;
+
+ for (Index = 0, NumLines = 0; Index < FileSize; Index++) {
+ if (FileBuffer[Index] == '\n') {
+ NumLines++;
+ }
+ }
+ PcdList = malloc((NumLines + 1) * sizeof(PcdList[0]));
+
+ for (Index = 0, TokenIndex = 0, PcdListLength = 0, TokenStart = 0; Index < FileSize; Index++) {
+ if (FileBuffer[Index] == ' ') {
+ continue;
+ }
+ if (FileBuffer[Index] == '|' || FileBuffer[Index] == '.' || FileBuffer[Index] == '\n' || FileBuffer[Index] == '\r') {
+ RecordToken (FileBuffer, PcdListLength, TokenIndex, TokenStart, Index);
+ if (FileBuffer[Index] == '\n' || FileBuffer[Index] == '\r') {
+ if (TokenIndex != 0) {
+ PcdListLength++;
+ TokenIndex = 0;
+ }
+ } else {
+ TokenIndex++;
+ }
+ TokenStart = Index + 1;
+ continue;
+ }
+ }
+ if (Index > TokenStart) {
+ RecordToken (FileBuffer, PcdListLength, TokenIndex, TokenStart, Index);
+ if (TokenIndex != 0) {
+ PcdListLength++;
+ }
+ }
+}
+
+VOID
+STATIC
+WriteOutputFile (
+ CHAR8 *OutputFileName
+ )
+{
+ FILE *OutputFile;
+ UINT32 Index;
+
+ //
+ // Open output file
+ //
+ OutputFile = fopen (OutputFileName, "wb");
+ if (OutputFile == NULL) {
+ fprintf (stderr, "Error opening file %s\n", OutputFileName);
+ exit (EXIT_FAILURE);
+ }
+
+ for (Index = 0; Index < PcdListLength; Index++) {
+ fprintf (
+ OutputFile,
+ "%s.%s.%s.%s|%s|%s\n",
+ PcdList[Index].SkuName,
+ PcdList[Index].DefaultValueName,
+ PcdList[Index].TokenSpaceGuidName,
+ PcdList[Index].TokenName,
+ PcdList[Index].DataType,
+ PcdList[Index].Value
+ );
+ }
+
+ //
+ // Done, write output file.
+ //
+ if (OutputFile != NULL) {
+ fclose (OutputFile);
+ }
+}
+
+VOID
+STATIC
+Usage (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Displays the utility usage syntax to STDOUT
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ fprintf (stdout, "Usage: -i <input_file> -o <output_file>\n\n");
+ fprintf (stdout, "optional arguments:\n");
+ fprintf (stdout, " -h, --help Show this help message and exit\n");
+ fprintf (stdout, " -i INPUT_FILENAME, --input INPUT_FILENAME\n\
+ PCD Database Input file name\n");
+ fprintf (stdout, " -o OUTPUT_FILENAME, --output OUTPUT_FILENAME\n\
+ PCD Database Output file name\n");
+}
+
+VOID
+STATIC
+ParseArguments (
+ int argc,
+ char *argv[],
+ CHAR8 **InputFileName,
+ CHAR8 **OutputFileName
+ )
+{
+ if (argc == 1) {
+ fprintf (stderr, "Missing options\n");
+ exit (EXIT_FAILURE);
+ }
+
+ //
+ // Parse command line
+ //
+ argc--;
+ argv++;
+
+ if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
+ Usage ();
+ exit (EXIT_SUCCESS);
+ }
+
+ while (argc > 0) {
+ if ((stricmp (argv[0], "-i") == 0) || (stricmp (argv[0], "--input") == 0)) {
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ fprintf (stderr, "Invalid option value. Input File name is missing for -i option\n");
+ exit (EXIT_FAILURE);
+ }
+ *InputFileName = argv[1];
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--output") == 0)) {
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ fprintf (stderr, "Invalid option value. Output File name is missing for -i option\n");
+ exit (EXIT_FAILURE);
+ }
+ *OutputFileName = argv[1];
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if (argv[0][0] == '-') {
+ fprintf (stderr, "Unknown option %s\n", argv[0]);
+ exit (EXIT_FAILURE);
+ }
+ argc --;
+ argv ++;
+ }
+
+ //
+ // Check Input paramters
+ //
+ if (*InputFileName == NULL) {
+ fprintf (stderr, "Missing option. Input files is not specified\n");
+ exit (EXIT_FAILURE);
+ } else {
+ printf ("Input file name is %s\n", *InputFileName);
+ }
+
+ if (*OutputFileName == NULL) {
+ fprintf (stderr, "Missing option. Output file is not specified\n");
+ exit (EXIT_FAILURE);
+ } else {
+ printf ("Output file name is %s\n", *OutputFileName);
+ }
+}
+
+int
+PcdValueMain (
+ int argc,
+ char *argv[]
+ )
+{
+ CHAR8 *InputFileName;
+ CHAR8 *OutputFileName;
+ UINT8 *FileBuffer;
+ UINT32 FileSize;
+
+ printf ("PCD tool start.\n");
+
+ //
+ //
+ //
+ ParseArguments (argc, argv, &InputFileName, &OutputFileName);
+
+ //
+ // Open Input file and read file data.
+ //
+ ReadInputFile (InputFileName, &FileBuffer, &FileSize);
+
+ //
+ //
+ //
+ ParseFile (FileBuffer, FileSize);
+
+ //
+ // Customize PCD values in the PCD Database
+ //
+ PcdEntryPoint ();
+
+ //
+ //
+ //
+ WriteOutputFile (OutputFileName);
+
+ printf ("PCD tool done.\n");
+
+ exit (EXIT_SUCCESS);
+}
diff --git a/BaseTools/Source/C/Common/PcdValueCommon.h b/BaseTools/Source/C/Common/PcdValueCommon.h
new file mode 100644
index 0000000..768d7a9
--- /dev/null
+++ b/BaseTools/Source/C/Common/PcdValueCommon.h
@@ -0,0 +1,78 @@
+/** @file
+Header file for CalcuateCrc32 routine
+
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
+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 _PCD_VALUE_COMMON_H
+#define _PCD_VALUE_COMMON_H
+
+#include <Common/UefiBaseTypes.h>
+
+#define __FIELD_SIZE(TYPE, Field) (sizeof((TYPE *)0)->Field)
+#define __ARRAY_ELEMENT_SIZE(TYPE, Field) (sizeof((TYPE *)0)->Field[0])
+#define __OFFSET_OF(TYPE, Field) ((UINT32) &(((TYPE *)0)->Field))
+#define __FLEXIBLE_SIZE(Size, TYPE, Field, MaxIndex) if (__FIELD_SIZE(TYPE, Field) == 0) Size = (__OFFSET_OF(TYPE, Field) + __ARRAY_ELEMENT_SIZE(TYPE, Field) * (MaxIndex))
+
+VOID
+PcdEntryPoint (
+ VOID
+ );
+
+int
+PcdValueMain (
+ int argc,
+ char *argv[]
+ );
+
+VOID
+__PcdSet (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName,
+ UINT64 Value
+ );
+
+VOID
+__PcdSet (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName,
+ UINT64 Value
+ );
+
+VOID *
+__PcdGetPtr (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName,
+ UINT32 *Size
+ );
+
+VOID
+__PcdSetPtr (
+ CHAR8 *SkuName OPTIONAL,
+ CHAR8 *DefaultValueName OPTIONAL,
+ CHAR8 *TokenSpaceGuidName,
+ CHAR8 *TokenName,
+ UINT32 Size,
+ UINT8 *Value
+ );
+
+#define PcdGet(A, B, C, D) __PcdGet(#A, #B, #C, #D)
+#define PcdSet(A, B, C, D, Value) __PcdSet(#A, #B, #C, #D, Value)
+#define PcdGetPtr(A, B, C, D, Size) __PcdGetPtr(#A, #B, #C, #D, Size)
+#define PcdSetPtr(A, B, C, D, Size, Value) __PcdSetPtr(#A, #B, #C, #D, Size, Value)
+
+#endif
diff --git a/BaseTools/Source/C/Makefiles/lib.makefile b/BaseTools/Source/C/Makefiles/lib.makefile
index bba76be..c592806 100644
--- a/BaseTools/Source/C/Makefiles/lib.makefile
+++ b/BaseTools/Source/C/Makefiles/lib.makefile
@@ -13,6 +13,8 @@
include $(MAKEROOT)/Makefiles/header.makefile
+BUILD_CFLAGS += -Wno-error
+
LIBRARY = $(MAKEROOT)/libs/lib$(LIBNAME).a
all: $(MAKEROOT)/libs $(LIBRARY)
--
2.8.0.windows.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [RFC 3/3] TestPkg: Show Structure PCD value assignment
2017-04-11 15:16 [RFC 0/3] Structure PCD value assignment in DEC/DSC Liming Gao
2017-04-11 15:16 ` [RFC 1/3] BaseTools: Update Makefile to work at absolute path Liming Gao
2017-04-11 15:16 ` [RFC 2/3] BaseTools: Add PcdValueCommon logic into CommonLib Liming Gao
@ 2017-04-11 15:16 ` Liming Gao
2017-04-11 15:24 ` [RFC 0/3] Structure PCD value assignment in DEC/DSC Laszlo Ersek
2017-05-05 6:00 ` Tim Lewis
4 siblings, 0 replies; 7+ messages in thread
From: Liming Gao @ 2017-04-11 15:16 UTC (permalink / raw)
To: edk2-devel
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Liming Gao <liming.gao@intel.com>
---
TestPkg/Include/Guid/Test.h | 31 ++
TestPkg/StructuredPcdValueGenerator.py | 702 +++++++++++++++++++++++++++++++++
TestPkg/TestPkg.dec | 44 +++
TestPkg/TestPkg.dsc | 69 ++++
4 files changed, 846 insertions(+)
create mode 100644 TestPkg/Include/Guid/Test.h
create mode 100644 TestPkg/StructuredPcdValueGenerator.py
create mode 100644 TestPkg/TestPkg.dec
create mode 100644 TestPkg/TestPkg.dsc
diff --git a/TestPkg/Include/Guid/Test.h b/TestPkg/Include/Guid/Test.h
new file mode 100644
index 0000000..e988954
--- /dev/null
+++ b/TestPkg/Include/Guid/Test.h
@@ -0,0 +1,31 @@
+//#pragma pack(1)
+
+#define MacroTest2 10
+
+typedef struct {
+ BOOLEAN Bool;
+ UINT8 A:4;
+ UINT8 B:4;
+ UINT32 Unaligned32;
+ UINT16 C;
+ UINT16 D;
+ UINT32 E;
+ UINT32 F;
+ UINT64 G;
+ UINT64 H;
+ UINT8 Reserved;
+ UINT8 Hidden;
+ UINT8 OneLine8;
+ UINT16 OneLine16;
+ UINT32 OneLine32;
+ UINT64 OneLine64;
+ BOOLEAN OneLineBoolA;
+ BOOLEAN OneLineBoolB;
+ BOOLEAN OneLineBoolC;
+ BOOLEAN OneLineBoolD;
+ UINT32 Array[10];
+ UINT8 Array2[2];
+ UINT8 FlexibleArray[0];
+} TEST;
+
+//#pragma pack()
diff --git a/TestPkg/StructuredPcdValueGenerator.py b/TestPkg/StructuredPcdValueGenerator.py
new file mode 100644
index 0000000..a24ccf3
--- /dev/null
+++ b/TestPkg/StructuredPcdValueGenerator.py
@@ -0,0 +1,702 @@
+#
+# Generate C program to convert structure PCD value to byte array.
+#
+
+import os
+import sys
+import argparse
+import subprocess
+from collections import OrderedDict
+import uuid
+
+#
+# Globals for help information
+#
+__prog__ = 'StructuredPcdValueGenerator'
+__version__ = '%s Version %s' % (__prog__, '0.1 ')
+__copyright__ = 'Copyright (c) 2017, Intel Corporation. All rights reserved.'
+__usage__ = '%s [options]' % (__prog__)
+
+#
+# Treat CHAR16 as a synonym for UINT16. CHAR16 support is required for VFR C structs
+#
+PcdValueInitName = 'PcdValueInit'
+PcdSupportedBaseTypes = ['BOOLEAN', 'UINT8', 'UINT16', 'UINT32', 'UINT64', 'CHAR16']
+PcdSupportedBaseTypeWidth = {'BOOLEAN':8, 'UINT8':8, 'UINT16':16, 'UINT32':32, 'UINT64':64}
+PcdUnsupportedBaseTypes = ['INT8', 'INT16', 'INT32', 'INT64', 'CHAR8', 'UINTN', 'INTN', 'VOID']
+
+PcdMainCHeader = '''
+/**
+ DO NOT EDIT
+ FILE auto-generated
+**/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <PcdValueCommon.h>
+'''
+
+PcdMainCEntry = '''
+int
+main (
+ int argc,
+ char *argv[]
+ )
+{
+ return PcdValueMain (argc, argv);
+}
+'''
+
+PcdMakefileHeader = '''
+#
+# DO NOT EDIT
+# This file is auto-generated by build utility
+#
+
+'''
+
+PcdMakefileEnd = '''
+!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common
+
+CFLAGS = $(CFLAGS) /wd4200 /wd4034
+
+LIBS = $(LIB_PATH)\Common.lib
+
+!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app
+'''
+
+PcdGccMakefile = '''
+ARCH ?= IA32
+MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C
+LIBS = -lCommon
+'''
+
+def GetBitField(Value, Start, Width):
+ Mask = (1 << Width) - 1
+ return (Value >> Start) & Mask
+
+def SetBitField(Value, Start, Width, BitFieldValue):
+ Mask = (1 << Width) - 1
+ if BitFieldValue & (~Mask) <> 0:
+ raise ValueError
+ BitFieldValue = BitFieldValue & Mask
+ Value = (Value & (~(Mask << Start))) | (BitFieldValue << Start)
+ return Value
+
+def IntToArray(Value, Size, Stride = 1, ValuesPerLine = 16, AsciiComment = False):
+ if Stride not in [1,2,4,8]:
+ return ''
+ PostFix = ''
+ if Stride == 8:
+ PostFix = 'ULL'
+ Value = Value & ((1 << Size * 8) - 1)
+ Output = '{\n'
+ Shift = Stride * 8
+ Mask = (1 << Shift) - 1
+ NumValues = 0
+ Ascii = ''
+ for Index in range (0, Size, Stride):
+ Output = Output + '0x%0*X%s' % (Stride * 2, Value & Mask, PostFix)
+ if Index + Stride < Size:
+ Output = Output + ', '
+ else:
+ Output = Output + ' '
+ for CharIndex in range (0, Stride):
+ Char = Value & 0xff
+ if Char in range(0x20, 0x7F):
+ Ascii = Ascii + chr(Value & 0xff)
+ else:
+ Ascii = Ascii + '.'
+ Value = Value >> 8
+ if (NumValues % ValuesPerLine) == (ValuesPerLine - 1):
+ if AsciiComment:
+ Output = Output + ' // %s' % (Ascii)
+ Output = Output + '\n'
+ Ascii = ''
+ NumValues = NumValues + 1
+ if AsciiComment and (NumValues % ValuesPerLine) <> 0:
+ for Index in range((NumValues % ValuesPerLine), ValuesPerLine):
+ Output = Output + ' %*s%*s ' % (Stride * 2, '', len(PostFix), '')
+ Output = Output + ' // %s\n' % (Ascii)
+ Output = Output + '}'
+ return Output
+
+def IntToCString(Value, ValueSize):
+ Result = '"'
+ if not isinstance (Value, str):
+ for Index in range(0, ValueSize):
+ Result = Result + '\\x%02x' % (Value & 0xff)
+ Value = Value >> 8
+ Result = Result + '"'
+ return Result
+
+def ParseFieldValue (Value):
+ if type(Value) == type(0):
+ return Value, (Value.bit_length() + 7) / 8
+ if type(Value) <> type(''):
+ raise ValueError
+ Value = Value.strip()
+ if Value.startswith('UINT8') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(',1)[1][:-1])
+ if Size > 1:
+ raise ValueError
+ return Value, 1
+ if Value.startswith('UINT16') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(',1)[1][:-1])
+ if Size > 2:
+ raise ValueError
+ return Value, 2
+ if Value.startswith('UINT32') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(',1)[1][:-1])
+ if Size > 4:
+ raise ValueError
+ return Value, 4
+ if Value.startswith('UINT64') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(',1)[1][:-1])
+ if Size > 8:
+ raise ValueError
+ return Value, 8
+ if Value.startswith('GUID') and Value.endswith(')'):
+ Value = Value.split('(',1)[1][:-1].strip()
+ if Value[0] == '{' and Value[-1] == '}':
+ Value = Value[1:-1].strip()
+ Value = Value.split('{',1)
+ Value = [Item.strip()[2:] for Item in (Value[0] + Value[1][:-1]).split(',')]
+ Value = '-'.join(Value[0:3]) + '-' + ''.join(Value[3:5]) + '-' + ''.join(Value[5:11])
+ if Value[0] == '"' and Value[-1] == '"':
+ Value = Value[1:-1]
+ Value = "'" + uuid.UUID(Value).get_bytes_le() + "'"
+ Value, Size = ParseFieldValue(Value)
+ return Value, 16
+ if Value.startswith('L"') and Value.endswith('"'):
+ # Unicode String
+ List = list(Value[2:-1])
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 16) | ord(Char)
+ return Value, (len(List) + 1) * 2
+ if Value.startswith('"') and Value.endswith('"'):
+ # ASCII String
+ List = list(Value[1:-1])
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 8) | ord(Char)
+ return Value, len(List) + 1
+ if Value.startswith("L'") and Value.endswith("'"):
+ # Unicode Character Constant
+ List = list(Value[2:-1])
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 16) | ord(Char)
+ return Value, len(List) * 2
+ if Value.startswith("'") and Value.endswith("'"):
+ # Character constant
+ List = list(Value[1:-1])
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 8) | ord(Char)
+ return Value, len(List)
+ if Value.startswith('{') and Value.endswith('}'):
+ # Byte array
+ Value = Value[1:-1]
+ List = [Item.strip() for Item in Value.split(',')]
+ List.reverse()
+ Value = 0
+ for Item in List:
+ ItemValue, Size = ParseFieldValue(Item)
+ if Size > 1:
+ raise ValueError
+ Value = (Value << 8) | ItemValue
+ return Value, len(List)
+ if Value.lower().startswith('0x'):
+ Value = int(Value, 16)
+ return Value, (Value.bit_length() + 7) / 8
+ if Value[0].isdigit():
+ Value = int(Value, 10)
+ return Value, (Value.bit_length() + 7) / 8
+ if Value.lower() == 'true':
+ return 1, 1
+ if Value.lower() == 'false':
+ return 0, 1
+ return Value, 1
+
+def IsFieldValueAnArray (Value):
+ Value = Value.strip()
+ if Value.startswith('GUID') and Value.endswith(')'):
+ return True
+ if Value.startswith('L"') and Value.endswith('"'):
+ return True
+ if Value[0] == '"' and Value[-1] == '"':
+ return True
+ if Value[0] == '{' and Value[-1] == '}':
+ return True
+ if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
+ print 'foo = ', list(Value[2:-1])
+ return True
+ if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
+ print 'bar = ', list(Value[1:-1])
+ return True
+ return False
+
+def ConvertValueToString (Value):
+ Result = ''
+ if Value.startswith('L"') and Value.endswith('"'):
+ for Char in Value[2:-1]:
+ Result = Result + '\\x%02x\\x00' % (ord(Char))
+ Result = Result + '\\x00\\x00'
+ if Value[0] == '"' and Value[-1] == '"':
+ for Char in Value[1:-1]:
+ Result = Result + '\\x%02x' % (ord(Char))
+ Result = Result + '\\x00'
+ if Value[0] == '{' and Value[-1] == '}':
+ Value = [int(Item.strip(),16) for Item in Value[1:-1].split(',')]
+ for Item in Value:
+ Result = Result + '\\x%02x' % (Item)
+ return Result
+
+def ExecuteCommand (Command):
+ try:
+ Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+ except:
+ print 'ERROR: Can not execute command:', Command
+ sys.exit(1)
+ Result = Process.communicate()
+ if Process.returncode <> 0:
+ print 'ERROR: Can not collect output from command:', Command
+ return Result[0], Result[1]
+
+class StructuredPcdField:
+ def __init__(self, FieldName, DefaultValue):
+ self.FieldName = FieldName
+ self.DefaultValue = DefaultValue
+
+ def __repr__(self):
+ return self.FieldName
+
+class StructuredPcd:
+ def __init__(self, StructuredPcdIncludeFile, Packages, TokenSpaceGuidName, TokenName, TypeName):
+ self.StructuredPcdIncludeFile = StructuredPcdIncludeFile
+ self.PackageDecs = Packages
+ self.SkuName = 'DEFAULT'
+ self.DefaultStoreName = 'DEFAULT'
+ self.TokenSpaceGuidName = TokenSpaceGuidName
+ self.TokenName = TokenName
+ self.TypeName = TypeName
+ self.DefaultValues = OrderedDict({})
+ self.PcdMode = None
+ self.OverrideValues = OrderedDict({})
+ self.FlexibleFieldName = None
+
+ def __repr__(self):
+ return self.TypeName
+
+ def AddDefaultValue (self, FieldName, Value, FileName="", LineNo=0):
+ self.DefaultValues[FieldName] = [Value.strip(), FileName, LineNo]
+ return self.DefaultValues[FieldName]
+
+ def AddOverrideValue (self, FieldName, Value, FileName="", LineNo=0):
+ self.OverrideValues[FieldName] = [Value.strip(), FileName, LineNo]
+ return self.OverrideValues[FieldName]
+
+ def SetPcdMode (self, PcdMode):
+ self.PcdMode = PcdMode
+
+ def SetFlexibleFieldName (self, FlexibleFieldName):
+ self.FlexibleFieldName = FlexibleFieldName
+
+class Build:
+ def __init__(self, args):
+ self.args = args
+ self.DecFile = args.DecFile
+ self.DscFile = args.DscFile
+ self.Quiet = args.Quiet
+ self.StructuredPcds = []
+ self.PackagePath = os.path.dirname(self.DecFile)
+ if os.getenv("WORKSPACE"):
+ self.OutputPath = os.path.join(os.getenv("WORKSPACE"), 'Build', PcdValueInitName)
+ else:
+ self.OutputPath = os.path.dirname(self.DscFile)
+
+ def __repr__(self):
+ return self.DscFile
+
+ def AddStructuredPcd (self, Include, Packages, TokenSpaceGuidName, TokenName, Type):
+ Pcd = StructuredPcd(Include, Packages, TokenSpaceGuidName, TokenName, Type)
+ self.StructuredPcds.append(Pcd)
+ return Pcd
+
+ def LookupPcd(self, TokenSpaceGuidName, TokenName):
+ for Pcd in self.StructuredPcds:
+ if Pcd.TokenSpaceGuidName == TokenSpaceGuidName and Pcd.TokenName == TokenName:
+ return Pcd
+ return None
+
+ def LookupPcdByTypeName(self, TypeName):
+ for Pcd in self.StructuredPcds:
+ if Pcd.TypeName == TypeName:
+ return Pcd
+ return None
+
+ def ParseDecFile (self):
+ print 'Parse DEC File', self.DecFile
+ File = open (self.DecFile, mode='r')
+ DecFileBuffer = File.readlines()
+ File.close()
+ DecLineNumber = 0
+ Include = None
+ PcdObject = None
+ while (DecLineNumber < len (DecFileBuffer)):
+ Line = DecFileBuffer[DecLineNumber]
+ DecLineNumber = DecLineNumber + 1
+ Line = Line.strip()
+ if Line.startswith('#'):
+ continue
+ if len(Line.split('|')) == 4:
+ Line = Line [:(len(Line)-1)]
+ Line = [Item.strip() for Item in Line.strip().split('|')]
+ Pcd = [Item.strip() for Item in Line[0].split('.',2)]
+ if len(Pcd) < 2:
+ print 'Error: PCD field sytnax error', DecLineNumber, Line
+ sys.exit()
+ elif len(Pcd) == 2:
+ TokenSpaceGuidName = Pcd[0]
+ TokenName = Pcd[1]
+ Type = Line[2]
+ Packages = []
+ NextLine = DecFileBuffer[DecLineNumber].strip()
+ DecLineNumber = DecLineNumber + 1
+ while (NextLine[0] != "}"):
+ if NextLine == "<HeaderFiles>":
+ Include = DecFileBuffer[DecLineNumber].strip()
+ DecLineNumber = DecLineNumber + 1
+ NextLine = DecFileBuffer[DecLineNumber].strip()
+ if NextLine == "<Packages>":
+ DecLineNumber = DecLineNumber + 1
+ NextLine = DecFileBuffer[DecLineNumber].strip()
+ while (NextLine[0] != "}" and NextLine[0] != "<"):
+ Packages.append (NextLine.strip().replace ('\\', '/'))
+ DecLineNumber = DecLineNumber + 1
+ NextLine = DecFileBuffer[DecLineNumber].strip()
+ DecLineNumber = DecLineNumber + 1
+ PcdObject = self.AddStructuredPcd (Include, Packages, TokenSpaceGuidName, TokenName, Type)
+ PcdObject.AddDefaultValue(Line[2], Line[1], self.DecFile, DecLineNumber)
+ elif PcdObject <> None:
+ Line = [Item.strip() for Item in Line.strip().split('|')]
+ Pcd = [Item.strip() for Item in Line[0].split('.',2)]
+ if len (Line) == 2 and len (Pcd) > 2:
+ if Pcd[0] <> PcdObject.TokenSpaceGuidName or Pcd[1] <> PcdObject.TokenName:
+ print 'Error: PCD does not match parent Structured PCD', Pcd[0], Pcd[1], TokenSpaceGuidName, TokenName
+ sys.exit()
+ PcdObject.AddDefaultValue('.' + Pcd[2], Line[1], self.DecFile, DecLineNumber)
+ if not self.args.Quiet:
+ for Pcd in self.StructuredPcds:
+ print 'Include : ', Pcd.StructuredPcdIncludeFile
+ print 'Type : ', Pcd.TypeName
+ print 'SkuName : ', Pcd.SkuName
+ print 'DefaultStoreName : ', Pcd.DefaultStoreName
+ print 'TokenSpaceGuid : ', Pcd.TokenSpaceGuidName
+ print 'TokenName : ', Pcd.TokenName
+ for Field in Pcd.DefaultValues:
+ print ' %40s : %s' % (Field, Pcd.DefaultValues[Field][0])
+ print ''
+
+ def ParseDscFile (self):
+ print 'Parse DSC File', self.DscFile
+ File = open (self.DscFile, mode='r')
+ DscFileBuffer = File.readlines()
+ File.close()
+ PcdMode = None
+ PcdFieldSettings = OrderedDict({})
+ DscLineNumber = 0
+ for Line in DscFileBuffer:
+ DscLineNumber = DscLineNumber + 1
+ if Line.startswith('#'):
+ continue
+ if Line.startswith('['):
+ Mode = Line[1:].split('.',1)[0].split(']',1)[0]
+ continue
+ Line = [Item.strip() for Item in Line.split('|')]
+ Pcd = [Item.strip() for Item in Line[0].split('.',2)]
+ if len(Pcd) >= 2 and len(Line) > 1:
+ PcdObject = self.LookupPcd (Pcd[0], Pcd[1])
+ if not PcdObject:
+ print 'ERROR: DSC file references structured PCD that is not declared in DEC file', Pcd[0], Pcd[1]
+ sys.exit()
+ if len (Pcd) == 2:
+ PcdObject.AddDefaultValue (PcdObject.TypeName, Line[1], self.DscFile, DscLineNumber)
+ else:
+ PcdObject.AddOverrideValue ('.' + Pcd[2], Line[1], self.DscFile, DscLineNumber)
+ if PcdMode and PcdMode <> Mode:
+ print '%d: %s: ERROR: PCD %s.%s has more than one mode %s %s.' % (DscLineNumber, self.DscFile, Pcd[0], Pcd[1], PcdMode, Mode)
+ sys.exit()
+ PcdMode = Mode
+ PcdObject.SetPcdMode(Mode)
+ if not self.args.Quiet:
+ for Pcd in self.StructuredPcds:
+ print 'Include : ', Pcd.StructuredPcdIncludeFile
+ print 'Type : ', Pcd.TypeName
+ print 'SkuName : ', Pcd.SkuName
+ print 'DefaultStoreName : ', Pcd.DefaultStoreName
+ print 'TokenSpaceGuid : ', Pcd.TokenSpaceGuidName
+ print 'TokenName : ', Pcd.TokenName
+ print 'PcdMode : ', Pcd.PcdMode
+ for Field in Pcd.DefaultValues:
+ print ' D %40s : %s' % (Field, Pcd.DefaultValues[Field][0])
+ for Field in Pcd.OverrideValues:
+ print ' O %40s : %s' % (Field, Pcd.OverrideValues[Field][0])
+ print ''
+
+ def GenerateByteArrayValue (self):
+ #
+ # Generate/Compile/Run C application to determine if there are any flexible array members
+ #
+ InitByteValue = ""
+ CApp = PcdMainCHeader
+
+ Includes = {}
+ for Pcd in self.StructuredPcds:
+ IncludeFile = Pcd.StructuredPcdIncludeFile
+ if IncludeFile not in Includes:
+ Includes[IncludeFile] = True
+ CApp = CApp + '#include <%s>\n' % (IncludeFile)
+ CApp = CApp + '\n'
+
+ FieldNames = {}
+ for Pcd in self.StructuredPcds:
+ CApp = CApp + 'void\n'
+ CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (Pcd.SkuName, Pcd.DefaultStoreName, Pcd.TokenSpaceGuidName, Pcd.TokenName)
+ CApp = CApp + ' void\n'
+ CApp = CApp + ' )\n'
+ CApp = CApp + '{\n'
+ CApp = CApp + ' UINT32 Size;\n'
+ CApp = CApp + ' UINT32 FieldSize;\n'
+ CApp = CApp + ' UINT8 *Value;\n'
+ CApp = CApp + ' %s *Pcd;\n' % (Pcd.TypeName)
+ CApp = CApp + ' UINT32 OriginalSize;\n'
+ CApp = CApp + ' VOID *OriginalPcd;\n'
+ CApp = CApp + '\n'
+ InitByteValue = '%s.%s.%s.%s|%s|' %(Pcd.SkuName, Pcd.DefaultStoreName, Pcd.TokenSpaceGuidName, Pcd.TokenName, Pcd.TypeName)
+
+ #
+ # Get current PCD value and size
+ #
+ CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (Pcd.SkuName, Pcd.DefaultStoreName, Pcd.TokenSpaceGuidName, Pcd.TokenName)
+ CApp = CApp + ' printf("OriginalSize = %d\\n", OriginalSize);\n'
+
+
+ #
+ # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
+ # the correct value. For structures with a flexible array member, the flexible
+ # array member is detected, and the size is based on the highest index used with
+ # the flexible array member. The flexible array member must be the last field
+ # in a structure. The size formula for this case is:
+ # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
+ #
+ CApp = CApp + ' Size = sizeof(%s);\n' % (Pcd.TypeName)
+ CApp = CApp + ' printf("Size = %d\\n", Size);\n'
+ for FieldList in [Pcd.DefaultValues, Pcd.OverrideValues]:
+ for FieldName in FieldList:
+ if not FieldName.startswith('.'):
+ continue
+ IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
+ if IsArray:
+ Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
+ CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s));\n' % (Pcd.TypeName, FieldName[1:], ValueSize, Pcd.TypeName, FieldName[1:]);
+ CApp = CApp + ' printf("Size = %d\\n", Size);\n'
+ else:
+ NewFieldName = ''
+ while '[' in FieldName:
+ NewFieldName = NewFieldName + FieldName.split('[',1)[0] + '[0]'
+ ArrayIndex = int(FieldName.split('[',1)[1].split(']',1)[0])
+ FieldName = FieldName.split(']',1)[1]
+ FieldName = NewFieldName + FieldName
+ while '[' in FieldName:
+ FieldName = FieldName.rsplit('[',1)[0]
+ #if not self.args.Quiet:
+ # print 'PCD Field: %40s' % (FieldName)
+ if Pcd.TypeName + FieldName not in FieldNames:
+ FieldNames[Pcd.TypeName + FieldName] = True
+ CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd.TypeName, FieldName[1:], ArrayIndex + 1)
+ CApp = CApp + ' printf("Size = %d\\n", Size);\n'
+ CApp = CApp + ' printf("Size = %d\\n", Size);\n'
+
+ #
+ # Allocate and zero buffer for the PCD
+ # Must handle cases where current value is smaller, larger, or same size
+ # Always keep that larger one as the current size
+ #
+ CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
+ CApp = CApp + ' printf("Size = %d\\n", Size);\n'
+ CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.TypeName)
+ CApp = CApp + ' memset (Pcd, 0, Size);\n'
+
+ #
+ # Copy current PCD value into allocated buffer.
+ #
+ CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
+
+ #
+ # Assign field values in PCD
+ #
+ for FieldList in [Pcd.DefaultValues, Pcd.OverrideValues]:
+ for FieldName in FieldList:
+ if not FieldName.startswith('.'):
+ InitByteValue = InitByteValue + '%s\n'%(FieldList[FieldName][0])
+ continue
+ IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
+ Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
+ #print FieldName, Value, ValueSize, IntToCString(Value, ValueSize)
+ if isinstance(Value, str):
+ CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName[1:], Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ elif IsArray:
+ #
+ # Use memcpy() to copy value into field
+ #
+ CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.TypeName, FieldName[1:])
+ CApp = CApp + ' printf("FieldSize = %d\\n", FieldSize);\n'
+ CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName[1:], ValueSize, ValueSize)
+ else:
+ if ValueSize > 4:
+ CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName[1:], Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ else:
+ CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName[1:], Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+
+ #
+ # Set new PCD value and size
+ #
+ CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (Pcd.SkuName, Pcd.DefaultStoreName, Pcd.TokenSpaceGuidName, Pcd.TokenName)
+
+ #
+ # Free PCD
+ #
+ CApp = CApp + ' free (Pcd);\n'
+
+ CApp = CApp + '}\n'
+ CApp = CApp + '\n'
+
+ CApp = CApp + 'VOID\n'
+ CApp = CApp + 'PcdEntryPoint(\n'
+ CApp = CApp + ' VOID\n'
+ CApp = CApp + ' )\n'
+ CApp = CApp + '{\n'
+ for Pcd in self.StructuredPcds:
+ CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (Pcd.SkuName, Pcd.DefaultStoreName, Pcd.TokenSpaceGuidName, Pcd.TokenName)
+ CApp = CApp + '}\n'
+
+ CApp = CApp + PcdMainCEntry + '\n'
+
+ if not os.path.exists(self.OutputPath):
+ os.makedirs(self.OutputPath)
+ CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
+ File = open (CAppBaseFileName + '.c', mode='w')
+ File.write(CApp)
+ File.close()
+
+ MakeApp = PcdMakefileHeader
+ if sys.platform == "win32":
+ MakeApp = MakeApp + 'APPNAME = %s\n' %(PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' %(self.OutputPath, PcdValueInitName) + 'INC = $(INC)'
+ else:
+ MakeApp = MakeApp + PcdGccMakefile
+ MakeApp = MakeApp + 'APPNAME = %s\n' %(PcdValueInitName) + 'OBJECTS = %s/%s.o\n' %(self.OutputPath, PcdValueInitName) + \
+ 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'BUILD_CFLAGS += -Wno-error\n' + 'INCLUDE +='
+ Packages = {}
+ for Pcd in self.StructuredPcds:
+ for PackageDec in Pcd.PackageDecs:
+ Package = PackageDec.split('/')[0]
+ if Package not in Packages:
+ Packages[Package] = True
+ MakeApp = MakeApp + ' -I $(WORKSPACE)/%s/Include' %(Package)
+ if Package == 'MdePkg':
+ MakeApp = MakeApp + ' -I $(WORKSPACE)/%s/Include/Ia32' %(Package)
+ MakeApp = MakeApp + '\n'
+ if sys.platform == "win32":
+ MakeApp = MakeApp + PcdMakefileEnd
+ MakeFileName = os.path.join(self.OutputPath, 'Makefile')
+ File = open (MakeFileName, mode='w')
+ File.write(MakeApp)
+ File.close()
+
+ InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
+ OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
+ File = open (InputValueFile, mode='w')
+ File.write(InitByteValue)
+ File.close()
+
+ if sys.platform == "win32":
+ StdOut, StdErr = ExecuteCommand ('nmake -f %s' % (MakeFileName))
+ else:
+ StdOut, StdErr = ExecuteCommand ('make -f %s' % (MakeFileName))
+ Messages = StdOut.split('\r')
+ for Message in Messages:
+ if " error " in Message:
+ FileInfo = Message.strip().split('(')
+ if len (FileInfo) > 0:
+ FileName = FileInfo [0]
+ FileLine = FileInfo [1].split (')')[0]
+ else:
+ FileInfo = Message.strip().split(':')
+ FileName = FileInfo [0]
+ FileLine = FileInfo [1]
+
+ File = open (FileName, mode='r')
+ FileData = File.readlines()
+ File.close()
+ print Message
+ print FileData[int (FileLine) - 1]
+ return
+
+ PcdValueInitExe = PcdValueInitName
+ if not sys.platform == "win32":
+ PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)
+
+ StdOut, StdErr = ExecuteCommand (PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile))
+ File = open (OutputValueFile, mode='r')
+ FileBuffer = File.readlines()
+ File.close()
+
+ print 'Final Value Output:'
+ for Pcd in FileBuffer:
+ PcdValue = Pcd.split ('|')
+ PcdInfo = PcdValue[0].split ('.')
+ print 'SkuName : ', PcdInfo[0]
+ print 'TokenSpaceGuid : ', PcdInfo[2]
+ print 'TokenName : ', PcdInfo[3]
+ print 'Value : ', PcdValue[2]
+
+def main():
+ #
+ # Create command line argument parser object
+ #
+ parser = argparse.ArgumentParser(prog=__prog__, version=__version__, usage=__usage__, description=__copyright__, conflict_handler='resolve')
+ parser.add_argument("-p", "--dec-file", dest='DecFile', help="DEC File", required = True)
+ parser.add_argument("-d", "--dsc-file", dest='DscFile', help="DSC File", required = True)
+ parser.add_argument("-v", "--verbose", dest='Verbose', action="store_true", help="increase output messages")
+ parser.add_argument("-q", "--quiet", dest='Quiet', action="store_true", help="reduce output messages")
+ parser.add_argument("--debug", dest='Debug', type=int, metavar='[0-9]', choices=range(0,10), default=0, help="set debug level")
+
+ #
+ # Parse command line arguments
+ #
+ args = parser.parse_args()
+
+ #
+ # Get absolute paths
+ #
+ args.DecFile = os.path.abspath(args.DecFile)
+ args.DscFile = os.path.abspath(args.DscFile)
+
+ #
+ #
+ #
+ BuildObject = Build(args)
+ BuildObject.ParseDecFile()
+ BuildObject.ParseDscFile()
+ BuildObject.GenerateByteArrayValue()
+
+if __name__ == '__main__':
+ main()
diff --git a/TestPkg/TestPkg.dec b/TestPkg/TestPkg.dec
new file mode 100644
index 0000000..622678e
--- /dev/null
+++ b/TestPkg/TestPkg.dec
@@ -0,0 +1,44 @@
+## @file TestPkg.dec
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License that 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]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = TestPkg
+ PACKAGE_GUID = F05BB314-CD00-4705-BD04-59B1CD9630E1
+ PACKAGE_VERSION = 0.1
+
+[Includes]
+ Include
+
+[LibraryClasses]
+
+[Guids]
+ ## MdeModule package token space guid
+ # Include/Guid/MdeModulePkgTokenSpace.h
+ gEfiStructuredPcdPkgTokenSpaceGuid = { 0x11a81069, 0xa6a2, 0x420a, { 0xa0, 0xe, 0x30, 0xc5, 0xb, 0xfb, 0xe8, 0x13 } }
+
+[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
+ # @Prompt Test Strucutre
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test|{0xFF, 0xFF}|TEST|0x00010071 {
+ <HeaderFiles>
+ Guid/Test.h
+ <Packages>
+ MdePkg/MdePkg.dec
+ TestPkg/TestPkg.dec
+ }
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.A|2
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.C|20
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array[4]|1
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array2[0]|2
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.FlexibleArray[7]|5
diff --git a/TestPkg/TestPkg.dsc b/TestPkg/TestPkg.dsc
new file mode 100644
index 0000000..fc61979
--- /dev/null
+++ b/TestPkg/TestPkg.dsc
@@ -0,0 +1,69 @@
+## @file
+# EFI/PI Reference Module Package for All Architectures
+#
+# (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
+# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# 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]
+ PLATFORM_NAME = StructuredPcdPkg
+ PLATFORM_GUID = 35B4419B-4CF6-46FA-9A5D-741D0D29CD61
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/StructuredPcdPkg
+ SUPPORTED_ARCHITECTURES = IA32|IPF|X64|EBC|ARM|AARCH64
+ BUILD_TARGETS = DEBUG|RELEASE|NOOPT
+ SKUID_IDENTIFIER = DEFAULT
+
+[LibraryClasses]
+
+###################################################################################################
+#
+# Components Section - list of the modules and components that will be processed by compilation
+# tools and the EDK II tools to generate PE32/PE32+/Coff image files.
+#
+# Note: The EDK II DSC file is not used to specify how compiled binary images get placed
+# into firmware volume images. This section is just a list of modules to compile from
+# source into UEFI-compliant binaries.
+# It is the FDF file that contains information on combining binary files into firmware
+# volume images, whose concept is beyond UEFI and is described in PI specification.
+# Binary modules do not need to be listed in this section, as they should be
+# specified in the FDF file. For example: Shell binary (Shell_Full.efi), FAT binary (Fat.efi),
+# Logo (Logo.bmp), and etc.
+# There may also be modules listed in this section that are not required in the FDF file,
+# When a module listed here is excluded from FDF file, then UEFI-compliant binary will be
+# generated for it, but the binary will not be put into any firmware volume.
+#
+###################################################################################################
+
+[PcdsFixedAtBuild]
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test|{0xFF, 0xFF}
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.A|MacroTest2
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.C|'a'
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array[4]|1
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array2[0]|2
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.FlexibleArray[7]|5
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.FlexibleArray[4]|L'C'
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.FlexibleArray[3]|'b'
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array|"Hello"
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array|L"Hello"
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array|'Hello'
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array|L'Hello'
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array|GUID("6F08F62E-5C19-498E-9157-B59CE6F362F1")
+# gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array|GUID({ 0x827495c7, 0x636f, 0x4e0c, { 0x9c, 0xcc, 0x93, 0x5e, 0xfb, 0x67, 0xf2, 0x7c } })
+# gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array|{1,2,3}
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.FlexibleArray|"World"
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.FlexibleArray|L"World"
+# gEfiStructuredPcdPkgTokenSpaceGuid.Test.FlexibleArray|{4, 5, 6}
+
+
+[Components]
--
2.8.0.windows.1
^ permalink raw reply related [flat|nested] 7+ messages in thread