public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH] BaseTools/GenBiosId: Add a new tool GenBiosId
@ 2019-05-28  1:32 Zhang, Shenglei
  2019-05-28 16:48 ` [edk2-devel] " Michael D Kinney
  0 siblings, 1 reply; 4+ messages in thread
From: Zhang, Shenglei @ 2019-05-28  1:32 UTC (permalink / raw)
  To: devel

GenBiosId is a tool to generate the BIOS ID binary file which uses
the data from the configuration file.
https://bugzilla.tianocore.org/show_bug.cgi?id=1846

Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com>
---
 BaseTools/Source/C/GenBiosId/GenBiosId.c | 627 +++++++++++++++++++++++
 BaseTools/Source/C/GNUmakefile           |   3 +-
 BaseTools/Source/C/GenBiosId/BiosId.env  |  27 +
 BaseTools/Source/C/GenBiosId/GNUmakefile |  14 +
 BaseTools/Source/C/GenBiosId/GenBiosId.h | 105 ++++
 BaseTools/Source/C/GenBiosId/Makefile    |  14 +
 BaseTools/Source/C/Makefile              |   3 +-
 7 files changed, 791 insertions(+), 2 deletions(-)
 create mode 100644 BaseTools/Source/C/GenBiosId/GenBiosId.c
 create mode 100644 BaseTools/Source/C/GenBiosId/BiosId.env
 create mode 100644 BaseTools/Source/C/GenBiosId/GNUmakefile
 create mode 100644 BaseTools/Source/C/GenBiosId/GenBiosId.h
 create mode 100644 BaseTools/Source/C/GenBiosId/Makefile

diff --git a/BaseTools/Source/C/GenBiosId/GenBiosId.c b/BaseTools/Source/C/GenBiosId/GenBiosId.c
new file mode 100644
index 000000000000..21d71d4ebd51
--- /dev/null
+++ b/BaseTools/Source/C/GenBiosId/GenBiosId.c
@@ -0,0 +1,627 @@
+/** @file
+This tool generates the BIOS ID binary file using the data from the configuration file.
+
+Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "GenBiosId.h"
+
+CHAR8          InputFileName[FILE_NAME_SIZE];
+CHAR8          OutputFileName[FILE_NAME_SIZE];
+CHAR8          OutputBatchFileName[FILE_NAME_SIZE];
+
+FILE          *InputFile;
+FILE          *OutputFile;
+FILE          *OutputBatchFile;
+
+BIOS_ID_IMAGE BiosIdImage = {
+  { '$', 'I', 'B', 'I', 'O', 'S', 'I', '$' },
+  {
+    { ATOU (' '), ATOU (' '), ATOU (' '), ATOU (' '), ATOU (' '), ATOU (' '), ATOU (' ') },
+    ATOU (' '),
+    ATOU ('.'),
+    { ATOU (' '), ATOU (' '), ATOU (' ') },
+    ATOU ('.'),
+    { ATOU ('0'), ATOU ('0'), ATOU ('0'), ATOU ('0') },
+    ATOU ('.'),
+    ATOU (' '),
+    { ATOU ('0'), ATOU ('0') },
+    ATOU ('.'),
+    { ATOU ('0'), ATOU ('0'), ATOU ('0'), ATOU ('0'), ATOU ('0'),
+      ATOU ('0'), ATOU ('0'), ATOU ('0'), ATOU ('0'), ATOU ('0') },
+    ATOU ('\0')
+  }
+};
+
+VOID
+PrintBanner (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+  printf ("\n");
+  printf ("GenBiosId utility, version: v1.0 05/27/2018   \n");
+  printf ("Copyright (c) 2019, Intel Corporation. All rights reserved.   \n");
+  printf ("\n");
+}
+
+VOID
+PrintUsage (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+  printf ("Usage:\n");
+  printf ("GenBiosId -i ConfigFile -o OutputFile [-ob OutputBatchFile] \n");
+  printf ("\n");
+}
+
+CHAR8 *
+StripLeadingWhiteSpace (
+  IN CHAR8 *StrInput
+  )
+/*++
+
+Routine Description:
+
+  Strip the leading whitespoace off the given ASCII string.
+
+Arguments:
+
+  StrInput  - the ASCII string that should be processed.
+
+Returns:
+
+  A pointer to the first non-whitespace character in the given string,
+  or NULL if the string was all whitespace.
+
+--*/
+{
+  if (StrInput == NULL) {
+    return NULL;
+  }
+
+  while (*StrInput != 0) {
+    if ((*StrInput == ' ') || (*StrInput == '\t') || (*StrInput == '\n')) {
+      ++StrInput;
+    } else {
+      return StrInput;
+    }
+  }
+
+  return NULL;
+}
+
+VOID
+ConvertToUnicode (
+  IN  CHAR8  *StrAscii,
+  OUT CHAR16 *StrUnicode
+  )
+/*++
+
+Routine Description:
+
+  Convert the given ASCII string to Unicode without appending terminating 0x0000.
+
+Arguments:
+
+  StrAscii    - the source ASCII string, null-terminated.
+
+  StrUnicode  - the resulted Unicode string will be put here, without the terminating 0x0000.
+
+Returns:
+
+--*/
+{
+  if ((StrAscii == NULL) || (StrUnicode == NULL)) {
+    return;
+  }
+
+  while (*StrAscii != 0) {
+    *StrUnicode = ATOU (*StrAscii);
+    ++StrAscii;
+    ++StrUnicode;
+  }
+}
+
+VOID
+FillTimeStamp (
+  OUT CHAR16  *StrTimeStampUnicode
+  )
+/*++
+
+Routine Description:
+  The function generates the current timestamp in "YYMMDDHHMM" format
+  and puts it into the Unicode string supplied, without the null-terminator.
+
+Arguments:
+
+  StrTimeStampUnicode - The Unicode string which is filled on return with the current timestamp.
+
+Returns:
+
+--*/
+{
+  struct tm *Time;
+  time_t    CurTime;
+  CHAR8     StrTime[11];
+
+  //
+  // Fetch the current time based on UTC timezone
+  //
+  time (&CurTime);
+  Time = gmtime (&CurTime);
+
+  if (NULL == Time) {
+    return;
+  }
+
+  sprintf (
+    StrTime,
+    "%02d%02d%02d%02d%02d",
+    (Time->tm_year + 1900) % 100, // Year is 1900-based, need only 2 digits.
+    Time->tm_mon + 1,             // Month is zero based.
+    Time->tm_mday,
+    Time->tm_hour,
+    Time->tm_min
+    );
+
+  ConvertToUnicode (StrTime, StrTimeStampUnicode);
+}
+
+VOID
+ConvertToAscii (
+  IN  CHAR16 *StrUnicode,
+  OUT CHAR8  *StrAscii
+  )
+/*++
+
+Routine Description:
+
+  Convert the given Unicode string to ASCII with appending terminating 0x00.
+
+Arguments:
+
+  StrUnicode  - the source Unicode string, null-terminated.
+
+  StrAscii    - the resulted ASCII string will be put here, with the terminating 0x00.
+
+Returns:
+
+--*/
+{
+  if ((StrUnicode == NULL) || (StrAscii == NULL)) {
+    return;
+  }
+
+  while (*StrUnicode != 0) {
+    *StrAscii = UTOA (*StrUnicode);
+    ++StrUnicode;
+    ++StrAscii;
+  }
+  *StrAscii = 0;
+}
+
+VOID
+PrintUnicodeString (
+  IN CHAR16 *StrUnicode
+  )
+/*++
+
+Routine Description:
+
+  Print the given Unicode string.
+
+Arguments:
+
+  StrUnicode  - the null-terminated Unicode string to print.
+
+Returns:
+
+--*/
+{
+  if (StrUnicode == NULL) {
+    return;
+  }
+
+  while (*StrUnicode != 0) {
+    putchar ((CHAR8)(*StrUnicode));
+    ++StrUnicode;
+  }
+}
+
+EFI_STATUS
+ParseInputFile (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Parse the BIOS ID definition file and fill the BIOS ID structure, including timestamp.
+
+Arguments:
+
+Returns:
+
+  EFI_SUCCESS           - The input file was parsed successfully.
+
+  EFI_INVALID_PARAMETER - The input file has incorrect format.
+
+--*/
+{
+  CHAR8   StrLine[MAX_LINE_SIZE];
+  CHAR8   StrFieldName[MAX_LINE_SIZE];
+  CHAR8   StrFieldValue[MAX_LINE_SIZE];
+  CHAR8   *Str;
+  UINT16  FieldsSet;
+  CHAR8   FormatString[MAX_FORMAT_STRING_SIZE];
+
+  FieldsSet = 0;
+  Str       = NULL;
+
+  //
+  // Generate the format string for sscanf() function.
+  //
+  sprintf (FormatString, "%%%us = %%%us", (unsigned int) sizeof (StrFieldName) - 1, (unsigned int) sizeof (StrFieldValue) - 1);
+
+  while (fgets (StrLine, sizeof (StrLine) - 1, InputFile) != NULL) {
+    Str = StripLeadingWhiteSpace (StrLine);
+
+    //
+    // Check for whitespace string.
+    //
+    if (Str == NULL) {
+      continue;
+    }
+
+    //
+    // Check for comment string.
+    //
+    if (*Str == '#') {
+      continue;
+    }
+
+    if (sscanf (Str, FormatString, StrFieldName, StrFieldValue) != 2) {
+      continue;
+    }
+
+    if (strcmp (StrFieldName, NAME_BOARD_ID) == 0) {
+      if (strlen (StrFieldValue) == CHARS_BOARD_ID) {
+        ConvertToUnicode (StrFieldValue, BiosIdImage.BiosIdString.BoardId);
+        FieldsSet |= FIELD_BOARD_ID;
+      } else {
+        printf ("Error: value of %s should have exactly %d chars\n", NAME_BOARD_ID, CHARS_BOARD_ID);
+        return EFI_INVALID_PARAMETER;
+      }
+    }
+
+    if (strcmp (StrFieldName, NAME_BOARD_REV) == 0) {
+      if (strlen (StrFieldValue) == CHARS_BOARD_REV) {
+        ConvertToUnicode (StrFieldValue, &(BiosIdImage.BiosIdString.BoardRev));
+        FieldsSet |= FIELD_BOARD_REV;
+      } else {
+        printf ("Error: value of %s should have exactly %d chars\n", NAME_BOARD_REV, CHARS_BOARD_REV);
+        return EFI_INVALID_PARAMETER;
+      }
+    }
+
+    if (strcmp (StrFieldName, NAME_BOARD_EXT) == 0) {
+      if (strlen (StrFieldValue) == CHARS_BOARD_EXT) {
+        ConvertToUnicode (StrFieldValue, BiosIdImage.BiosIdString.BoardExt);
+        FieldsSet |= FIELD_BOARD_EXT;
+      } else {
+        printf ("Error: value of %s should have exactly %d chars\n", NAME_BOARD_EXT, CHARS_BOARD_EXT);
+        return EFI_INVALID_PARAMETER;
+      }
+    }
+
+    if (strcmp (StrFieldName, NAME_BUILD_TYPE) == 0) {
+      if (strlen (StrFieldValue) == CHARS_BUILD_TYPE) {
+        if ((strcmp (StrFieldValue, "D") == 0) ||
+            (strcmp (StrFieldValue, "A") == 0) ||
+            (strcmp (StrFieldValue, "B") == 0) ||
+            (strcmp (StrFieldValue, "P") == 0)) {
+          ConvertToUnicode (StrFieldValue, &(BiosIdImage.BiosIdString.BuildType));
+          FieldsSet |= FIELD_BUILD_TYPE;
+        } else {
+          printf ("Error: value of %s should be one of %s, %s, %s or %s\n", NAME_BUILD_TYPE, "D", "A", "B", "P");
+          return EFI_INVALID_PARAMETER;
+        }
+      } else {
+        printf ("Error: value of %s should have exactly %d chars\n", NAME_BUILD_TYPE, CHARS_BUILD_TYPE);
+        return EFI_INVALID_PARAMETER;
+      }
+    }
+
+    if (strcmp (StrFieldName, NAME_VERSION_MAJOR) == 0) {
+      if (strlen (StrFieldValue) == CHARS_VERSION_MAJOR) {
+        ConvertToUnicode (StrFieldValue, BiosIdImage.BiosIdString.VersionMajor);
+        FieldsSet |= FIELD_VERSION_MAJOR;
+      } else {
+        printf ("Error: value of %s should have exactly %d chars\n", NAME_VERSION_MAJOR, CHARS_VERSION_MAJOR);
+        return EFI_INVALID_PARAMETER;
+      }
+    }
+
+    if (strcmp (StrFieldName, NAME_VERSION_MINOR) == 0) {
+      if (strlen (StrFieldValue) == CHARS_VERSION_MINOR) {
+        ConvertToUnicode (StrFieldValue, BiosIdImage.BiosIdString.VersionMinor);
+        FieldsSet |= FIELD_VERSION_MINOR;
+      } else {
+        printf ("Error: value of %s should have exactly %d chars\n", NAME_VERSION_MINOR, CHARS_VERSION_MINOR);
+        return EFI_INVALID_PARAMETER;
+      }
+    }
+
+    if (strcmp (StrFieldName, NAME_DATE) == 0) {
+      if (strlen (StrFieldValue) == CHARS_DATE) {
+        ConvertToUnicode (StrFieldValue, BiosIdImage.BiosIdString.TimeStamp);
+        FieldsSet |= FIELD_DATE;
+      } else {
+        printf ("Error: value of %s should have exactly %d chars\n", NAME_DATE, CHARS_DATE);
+        return EFI_INVALID_PARAMETER;
+      }
+    }
+
+    if (strcmp (StrFieldName, NAME_TIME) == 0) {
+      if (strlen (StrFieldValue) == CHARS_TIME) {
+        ConvertToUnicode (StrFieldValue, &(BiosIdImage.BiosIdString.TimeStamp[CHARS_DATE]));
+        FieldsSet |= FIELD_TIME;
+      } else {
+        printf ("Error: value of %s should have exactly %d chars\n", NAME_TIME, CHARS_TIME);
+        return EFI_INVALID_PARAMETER;
+      }
+    }
+
+  }
+
+  if ((FieldsSet & (FIELD_DATE | FIELD_TIME)) != (FIELD_DATE | FIELD_TIME)) {
+    //
+    // Fill the timestamp.
+    //
+    FillTimeStamp (BiosIdImage.BiosIdString.TimeStamp);
+    FieldsSet |= (FIELD_DATE | FIELD_TIME);
+  }
+
+  //
+  // Exit if not all fields were supplied.
+  //
+  if ((FieldsSet & FIELD_ALL) != FIELD_ALL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+WriteOutputFile (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Write the BIOS ID structure to the output file.
+
+Arguments:
+
+Returns:
+
+  EFI_SUCCESS       - The output file was created successfully.
+
+  EFI_DEVICE_ERROR  - There was a file write error.
+
+--*/
+{
+  if (fwrite (&BiosIdImage, sizeof (BIOS_ID_IMAGE), 1, OutputFile) != 1) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+WriteOutputBatchFile (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Write "SET BIOS_ID=" and BIOS ID string to the batch file.
+
+Arguments:
+
+Returns:
+
+  EFI_SUCCESS       - The output batch file was created successfully.
+
+  EFI_DEVICE_ERROR  - There was a file write error.
+
+--*/
+{
+#ifndef __GNUC__
+  CHAR8 BatchFileContent[MAX_LINE_SIZE] = "SET BIOS_ID=";
+#else
+  CHAR8 BatchFileContent[MAX_LINE_SIZE] = "export BIOS_ID=";
+#endif
+
+  CHAR8 BiosIdString[sizeof (BIOS_ID_STRING)];
+
+  ConvertToAscii ((CHAR16 *) (&(BiosIdImage.BiosIdString)), BiosIdString);
+  strcat (BatchFileContent, BiosIdString);
+
+  if (fwrite (BatchFileContent, strlen (BatchFileContent), 1, OutputBatchFile) != 1) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+int
+main (
+  IN  int   argc,
+  IN  CHAR8 *argv[]
+  )
+/*++
+
+Routine Description:
+
+Arguments:
+
+  argc  - Number of command-line arguments.
+
+  argv  - Array of command-line arguments.
+
+Returns:
+
+  0   - The operation completed successfully.
+
+  -1  - An error occurred.
+
+--*/
+{
+  int Status;
+
+  Status = 0;
+
+  PrintBanner ();
+
+  if ((argc != 5) && (argc != 7)) {
+    PrintUsage ();
+    Status = -1;
+    goto Done;
+  }
+
+  if (strcmp (argv[1], "-i") == 0) {
+    if (strlen (argv[2])> sizeof (InputFileName) - 1) {
+      printf ("The InputFileName %s is too long \n", argv[2]);
+      Status = -1;
+      goto Done;
+    }
+    strncpy (InputFileName, argv[2], sizeof (InputFileName) - 1);
+    InputFileName[sizeof (InputFileName) - 1] = 0;
+  } else {
+    PrintUsage ();
+    Status = -1;
+    goto Done;
+  }
+
+  if (strcmp (argv[3], "-o") == 0) {
+    if (strlen (argv[4])> sizeof (OutputFileName) - 1) {
+      printf ("OutputFileName %s is too long \n", argv[4]);
+      Status = -1;
+      goto Done;
+    }
+    strncpy (OutputFileName, argv[4], sizeof (OutputFileName) - 1);
+    OutputFileName[sizeof (OutputFileName) - 1] = 0;
+  } else {
+    PrintUsage ();
+    Status = -1;
+    goto Done;
+  }
+
+  if (argc == 7) {
+    if (strcmp (argv[5], "-ob") == 0) {
+      if (strlen (argv[6])> sizeof (OutputBatchFileName) - 1) {
+        printf ("The OutputBatchFileName %s is too long \n", argv[6]);
+        Status = -1;
+        goto Done;
+      }
+      strncpy (OutputBatchFileName, argv[6], sizeof (OutputBatchFileName) - 1);
+      OutputBatchFileName[sizeof (OutputBatchFileName) - 1] = 0;
+    } else {
+      PrintUsage ();
+      Status = -1;
+      goto Done;
+    }
+  }
+
+  InputFile   = NULL;
+  OutputFile  = NULL;
+  OutputBatchFile = NULL;
+
+  InputFile   = fopen (InputFileName, "r");
+  if (InputFile == NULL) {
+    printf ("Error opening input file: %s\n", InputFileName);
+    Status = -1;
+    goto Done;
+  }
+
+  OutputFile  = fopen (OutputFileName, "wb");
+  if (OutputFile == NULL) {
+    printf ("Error creating output file: %s\n", OutputFileName);
+    Status = -1;
+    goto Done;
+  }
+
+  if (argc == 7) {
+    OutputBatchFile = fopen (OutputBatchFileName, "wb");
+    if (OutputBatchFile == NULL) {
+      printf ("Error creating output batch file: %s\n", OutputBatchFileName);
+      Status = -1;
+      goto Done;
+    }
+  }
+
+  if (ParseInputFile () != EFI_SUCCESS) {
+    printf ("Invalid config file format: %s\n", InputFileName);
+    Status = -1;
+    goto Done;
+  }
+
+  if (WriteOutputFile () != EFI_SUCCESS) {
+    printf ("Can't write output file: %s\n", OutputFileName);
+    Status = -1;
+    goto Done;
+  }
+
+  if (argc == 7) {
+    if (WriteOutputBatchFile () != EFI_SUCCESS) {
+      printf ("Can't write output batch file: %s\n", OutputBatchFileName);
+      Status = -1;
+      goto Done;
+    }
+  }
+
+  printf ("BIOS ID created: ");
+  PrintUnicodeString ((CHAR16 *)(&(BiosIdImage.BiosIdString)));
+  printf ("\n");
+  printf ("BIOS ID binary file created: %s\n", OutputFileName);
+
+Done:
+
+  if (InputFile != NULL) {
+    fclose (InputFile);
+  }
+
+  if (OutputFile != NULL) {
+    fclose (OutputFile);
+  }
+
+  if (OutputBatchFile != NULL) {
+    fclose (OutputBatchFile);
+  }
+
+  return Status;
+}
+
diff --git a/BaseTools/Source/C/GNUmakefile b/BaseTools/Source/C/GNUmakefile
index 37bcce519c7e..9dbf1a4b06db 100644
--- a/BaseTools/Source/C/GNUmakefile
+++ b/BaseTools/Source/C/GNUmakefile
@@ -1,7 +1,7 @@
 ## @file
 #  GNU/Linux makefile for C tools build.
 #
-#  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -47,6 +47,7 @@ VFRAUTOGEN = VfrCompile/VfrLexer.h
 APPLICATIONS = \
   BrotliCompress \
   VfrCompile \
+  GenBiosId \
   EfiRom \
   GenFfs \
   GenFv \
diff --git a/BaseTools/Source/C/GenBiosId/BiosId.env b/BaseTools/Source/C/GenBiosId/BiosId.env
new file mode 100644
index 000000000000..de54273107bd
--- /dev/null
+++ b/BaseTools/Source/C/GenBiosId/BiosId.env
@@ -0,0 +1,27 @@
+## @file
+#  This file is used to define the BIOS ID parameters of the build.
+#  This file is processed by GenBiosId.
+#  Here, it is just a template and can be customized by user.
+#
+#  BIOS ID string format:
+#    $(BOARD_ID)$(BOARD_REV).$(BOARD_EXT).$(VERSION_MAJOR).$(BUILD_TYPE)$(VERSION_MINOR).YYMMDDHHMM
+#  All fields must have a fixed length. YYMMDDHHMM is UTC time.
+#    Example: "OVMF.000.0008.D03.1501301017"
+#
+#  If DATE is specified for YYMMDD and TIME is specified for HHMM like below,
+#  GenBiosId will use the value of DATE and TIME to fill YYMMDDHHMM,
+#  otherwise GenBiosId will fill YYMMDDHHMM with current UTC time of the build machine.
+#    DATE          = 150130
+#    TIME          = 1017
+#
+# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+BOARD_ID      = OVMF
+BOARD_REV     = 1
+BOARD_EXT     = 000
+BUILD_TYPE    = D
+VERSION_MAJOR = 0008
+VERSION_MINOR = 03
diff --git a/BaseTools/Source/C/GenBiosId/GNUmakefile b/BaseTools/Source/C/GenBiosId/GNUmakefile
new file mode 100644
index 000000000000..90a918c13f96
--- /dev/null
+++ b/BaseTools/Source/C/GenBiosId/GNUmakefile
@@ -0,0 +1,14 @@
+## @file
+#  makefile for building the GenBiosId utility.
+#
+# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+MAKEROOT ?= ..
+
+APPNAME = GenBiosId
+
+OBJECTS = GenBiosId.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
diff --git a/BaseTools/Source/C/GenBiosId/GenBiosId.h b/BaseTools/Source/C/GenBiosId/GenBiosId.h
new file mode 100644
index 000000000000..660fba77e90b
--- /dev/null
+++ b/BaseTools/Source/C/GenBiosId/GenBiosId.h
@@ -0,0 +1,105 @@
+/** @file
+Definitions for the GenBiosId tool.
+
+Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _GEN_BIOS_ID_
+#define _GEN_BIOS_ID_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <Common/UefiBaseTypes.h>
+
+#define FILE_NAME_SIZE  256
+#define MAX_LINE_SIZE   256
+#define MAX_FORMAT_STRING_SIZE  64
+
+#define ATOU(a)         (CHAR16) ((UINT8) (a))
+#define UTOA(a)         (CHAR8) ((UINT16) (a))
+
+//
+// BIOS ID field names.
+//
+#define NAME_BOARD_ID       "BOARD_ID"
+#define NAME_BOARD_REV      "BOARD_REV"
+#define NAME_BOARD_EXT      "BOARD_EXT"
+#define NAME_BUILD_TYPE     "BUILD_TYPE"
+#define NAME_VERSION_MAJOR  "VERSION_MAJOR"
+#define NAME_VERSION_MINOR  "VERSION_MINOR"
+#define NAME_DATE           "DATE"
+#define NAME_TIME           "TIME"
+
+//
+// Number of ASCII characters in each field
+//
+#define CHARS_BOARD_ID      7
+#define CHARS_BOARD_REV     1
+#define CHARS_BOARD_EXT     3
+#define CHARS_BUILD_TYPE    1
+#define CHARS_VERSION_MAJOR 4
+#define CHARS_VERSION_MINOR 2
+#define CHARS_DATE          6
+#define CHARS_TIME          4
+
+#define FIELD_BOARD_ID      0x0001
+#define FIELD_BOARD_REV     0x0002
+#define FIELD_BOARD_EXT     0x0004
+#define FIELD_BUILD_TYPE    0x0008
+#define FIELD_VERSION_MAJOR 0x0010
+#define FIELD_VERSION_MINOR 0x0020
+#define FIELD_DATE          0x0040
+#define FIELD_TIME          0x0080
+
+#define FIELD_ALL (     \
+  FIELD_BOARD_ID      | \
+  FIELD_BOARD_REV     | \
+  FIELD_BOARD_EXT     | \
+  FIELD_BUILD_TYPE    | \
+  FIELD_VERSION_MAJOR | \
+  FIELD_VERSION_MINOR | \
+  FIELD_DATE          | \
+  FIELD_TIME)
+
+//
+// BIOS ID string format:
+//
+// $(BOARD_ID)$(BOARD_REV).$(BOARD_EXT).$(VERSION_MAJOR).$(BUILD_TYPE)$(VERSION_MINOR).YYMMDDHHMM
+//
+// Example: "TRFTCRB1.000.0008.D03.1501301017"
+//
+// The format should be same as platform BIOS ID definition
+//
+#pragma pack(1)
+
+typedef struct {
+  CHAR16    BoardId[7];             // "TRFTCRB"
+  CHAR16    BoardRev;               // "1"
+  CHAR16    Dot1;                   // "."
+  CHAR16    BoardExt[3];            // "000"
+  CHAR16    Dot2;                   // "."
+  CHAR16    VersionMajor[4];        // "0008"
+  CHAR16    Dot3;                   // "."
+  CHAR16    BuildType;              // "D"
+  CHAR16    VersionMinor[2];        // "03"
+  CHAR16    Dot4;                   // "."
+  CHAR16    TimeStamp[10];          // "YYMMDDHHMM"
+  CHAR16    NullTerminator;         // 0x0000
+} BIOS_ID_STRING;
+
+//
+// A signature precedes the BIOS ID string in the FV to enable search by external tools.
+//
+typedef struct {
+  UINT8             Signature[8];   // "$IBIOSI$"
+  BIOS_ID_STRING    BiosIdString;   // "TRFTCRB1.000.0008.D03.1501301017"
+} BIOS_ID_IMAGE;
+
+#pragma pack()
+
+
+#endif // _GEN_BIOS_ID_
diff --git a/BaseTools/Source/C/GenBiosId/Makefile b/BaseTools/Source/C/GenBiosId/Makefile
new file mode 100644
index 000000000000..967a1809b635
--- /dev/null
+++ b/BaseTools/Source/C/GenBiosId/Makefile
@@ -0,0 +1,14 @@
+## @file
+#  makefile for building the GenBiosId utility.
+#
+# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+!INCLUDE ..\Makefiles\ms.common
+
+APPNAME = GenBiosId
+
+OBJECTS = GenBiosId.obj
+
+!INCLUDE ..\Makefiles\ms.app
+
diff --git a/BaseTools/Source/C/Makefile b/BaseTools/Source/C/Makefile
index 217fc2b91d7b..748565bba9ff 100644
--- a/BaseTools/Source/C/Makefile
+++ b/BaseTools/Source/C/Makefile
@@ -1,7 +1,7 @@
 ## @file
 # Windows makefile for C tools build.
 #
-# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
 # SPDX-License-Identifier: BSD-2-Clause-Patent
 #
 HOST_ARCH = IA32
@@ -12,6 +12,7 @@ LIBRARIES = Common
 APPLICATIONS = \
   VfrCompile \
   BrotliCompress \
+  GenBiosId \
   EfiRom \
   GenCrc32 \
   GenFfs \
-- 
2.18.0.windows.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread
* [PATCH] BaseTools/GenBiosId: Add a new tool GenBiosId
@ 2019-06-14  7:38 Zhang, Shenglei
  2019-06-14 15:06 ` [edk2-devel] " Michael D Kinney
  0 siblings, 1 reply; 4+ messages in thread
From: Zhang, Shenglei @ 2019-06-14  7:38 UTC (permalink / raw)
  To: devel; +Cc: Fan, Zhiju, Bob Feng, Liming Gao

From: "Fan, Zhiju" <zhijux.fan@intel.com>

GenBiosId is a tool to generate the BIOS ID binary file which uses
the data from the configuration file.
https://bugzilla.tianocore.org/show_bug.cgi?id=1846

v2:v1 is a tool of C type and v2 is python type.

Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com>
---
 BaseTools/BinWrappers/PosixLike/GenBiosId     |  14 +++
 .../BinWrappers/WindowsLike/GenBiosId.bat     |   3 +
 BaseTools/Source/Python/GenBiosId/BiosId.env  |  27 +++++
 .../Source/Python/GenBiosId/GenBiosId.py      | 108 ++++++++++++++++++
 4 files changed, 152 insertions(+)
 create mode 100644 BaseTools/BinWrappers/PosixLike/GenBiosId
 create mode 100644 BaseTools/BinWrappers/WindowsLike/GenBiosId.bat
 create mode 100644 BaseTools/Source/Python/GenBiosId/BiosId.env
 create mode 100644 BaseTools/Source/Python/GenBiosId/GenBiosId.py

diff --git a/BaseTools/BinWrappers/PosixLike/GenBiosId b/BaseTools/BinWrappers/PosixLike/GenBiosId
new file mode 100644
index 000000000000..9fb68299e4c6
--- /dev/null
+++ b/BaseTools/BinWrappers/PosixLike/GenBiosId
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+#python `dirname $0`/RunToolFromSource.py `basename $0` $*
+
+# If a ${PYTHON_COMMAND} command is available, use it in preference to python
+if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
+    python_exe=${PYTHON_COMMAND}
+fi
+
+full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
+dir=$(dirname "$full_cmd")
+exe=$(basename "$full_cmd")
+
+export PYTHONPATH="$dir/../../Source/Python${PYTHONPATH:+:"$PYTHONPATH"}"
+exec "${python_exe:-python}" "$dir/../../Source/Python/$exe/$exe.py" "$@"
diff --git a/BaseTools/BinWrappers/WindowsLike/GenBiosId.bat b/BaseTools/BinWrappers/WindowsLike/GenBiosId.bat
new file mode 100644
index 000000000000..9616cd893bec
--- /dev/null
+++ b/BaseTools/BinWrappers/WindowsLike/GenBiosId.bat
@@ -0,0 +1,3 @@
+@setlocal
+@set ToolName=%~n0%
+@%PYTHON_COMMAND% %BASE_TOOLS_PATH%\Source\Python\%ToolName%\%ToolName%.py %*
diff --git a/BaseTools/Source/Python/GenBiosId/BiosId.env b/BaseTools/Source/Python/GenBiosId/BiosId.env
new file mode 100644
index 000000000000..92805e3cb78c
--- /dev/null
+++ b/BaseTools/Source/Python/GenBiosId/BiosId.env
@@ -0,0 +1,27 @@
+## @file
+#  This file is used to define the BIOS ID parameters of the build.
+#  This file is processed by GenBiosId.
+#  Here, it is just a template and can be customized by user.
+#
+#  BIOS ID string format:
+#    $(BOARD_ID)$(BOARD_REV).$(BOARD_EXT).$(VERSION_MAJOR).$(BUILD_TYPE)$(VERSION_MINOR).YYMMDDHHMM
+#  All fields must have a fixed length. YYMMDDHHMM is UTC time.
+#    Example: "EMLATOR1.000.0001.D01.1906141517"
+#
+#  If DATE is specified for YYMMDD and TIME is specified for HHMM like below,
+#  GenBiosId will use the value of DATE and TIME to fill YYMMDDHHMM,
+#  otherwise GenBiosId will fill YYMMDDHHMM with current UTC time of the build machine.
+#    DATE          = 190614
+#    TIME          = 1517
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+[config]
+BOARD_ID      = EMLATOR
+BOARD_REV     = 1
+BOARD_EXT     = 000
+BUILD_TYPE    = D
+VERSION_MAJOR = 0001
+VERSION_MINOR = 01
diff --git a/BaseTools/Source/Python/GenBiosId/GenBiosId.py b/BaseTools/Source/Python/GenBiosId/GenBiosId.py
new file mode 100644
index 000000000000..1be99f4a5931
--- /dev/null
+++ b/BaseTools/Source/Python/GenBiosId/GenBiosId.py
@@ -0,0 +1,108 @@
+## @file
+# Trim files preprocessed by compiler
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+##
+# Import Modules
+#
+import Common.LongFilePathOs as os
+import sys
+import struct
+import time
+import datetime
+try:
+    from configparser import ConfigParser
+except:
+    from ConfigParser import ConfigParser
+from Common.BuildToolError import *
+from Common.Misc import *
+from Common.DataType import *
+from Common.BuildVersion import gBUILD_VERSION
+import Common.EdkLogger as EdkLogger
+from Common.LongFilePathSupport import OpenLongFilePath as open
+
+_BIOS_Signature = "$IBIOSI$"
+_SectionKeyName = '__name__'
+_SectionName = 'config'
+
+_ConfigItem = {
+    "BOARD_ID"   : {'Value' : '', 'Length' : 7},
+    "BOARD_REV"  : {'Value' : '', 'Length' : 1},
+    "BOARD_EXT"  : { 'Value' : '', 'Length' : 3},
+    "BUILD_TYPE" : {'Value' : '', 'Length' :1},
+    "VERSION_MAJOR" : {'Value' : '0000', 'Length' : 4},
+    "VERSION_MINOR" : {'Value' : '00', 'Length' : 2},
+
+}
+
+
+_Usage = "Usage: GenBiosId -i Configfile -o OutputFile [-ob OutputBatchFile]"
+_ConfigSectionNotDefine = "Not support the config file format, need config section"
+_ConfigLenInvalid = "Config item %s length is invalid"
+_ConfigItemInvalid = "Item %s is invalid"
+
+def Main():
+    try:
+        EdkLogger.Initialize()
+        if len(sys.argv) !=5 and len(sys.argv) != 7:
+            EdkLogger.error("GenBiosId", OPTION_MISSING, ExtraData=_Usage)
+    except FatalError as X:
+        return 1
+    InputFile = ''
+    OutputFile = ''
+    OutputBatchFile = ''
+    for Index, Item in enumerate(sys.argv):
+        if '-i' == Item:
+            InputFile = sys.argv[Index + 1]
+        if '-o' == Item:
+            OutputFile = sys.argv[Index + 1]
+        if '-ob' == Item:
+            OutputBatchFile = sys.argv[Index + 1]
+    if not os.path.exists(InputFile):
+        EdkLogger.error("GenBiosId", FILE_NOT_FOUND, ExtraData="Input file not found")
+    cf = ConfigParser()
+    cf.optionxform = str
+    cf.read(InputFile)
+    if _SectionName not in cf._sections:
+        EdkLogger.error("GenBiosId", FORMAT_NOT_SUPPORTED, ExtraData=_ConfigSectionNotDefine)
+    for Item in cf._sections[_SectionName]:
+        if Item == _SectionKeyName:
+            continue
+        if Item not in _ConfigItem:
+            EdkLogger.error("GenBiosId", FORMAT_INVALID, ExtraData=_ConfigItemInvalid % Item)
+        _ConfigItem[Item]['Value'] = cf._sections[_SectionName][Item]
+        if len(_ConfigItem[Item]['Value']) != _ConfigItem[Item]['Length']:
+            EdkLogger.error("GenBiosId", FORMAT_INVALID, ExtraData=_ConfigLenInvalid % Item)
+    for Item in _ConfigItem:
+        if not _ConfigItem[Item]['Value']:
+            EdkLogger.error("GenBiosId", FORMAT_UNKNOWN_ERROR, ExtraData="Item %s is missing" % Item)
+    utcnow = datetime.datetime.utcnow()
+    TimeStamp = time.strftime("%y%m%d%H%M", utcnow.timetuple())
+
+    Id_Str = _ConfigItem['BOARD_ID']['Value'] + _ConfigItem['BOARD_REV']['Value'] + '.' + _ConfigItem['BOARD_EXT']['Value'] + '.' + _ConfigItem['VERSION_MAJOR']['Value'] + \
+             '.' + _ConfigItem["BUILD_TYPE"]['Value'] + _ConfigItem['VERSION_MINOR']['Value'] + '.' + TimeStamp
+    with open(OutputFile, 'wb') as FdOut:
+        for i in _BIOS_Signature:
+            FdOut.write(struct.pack('B', ord(i)))
+
+        for i in Id_Str:
+            FdOut.write(struct.pack('H', ord(i)))
+
+        FdOut.write(struct.pack('H', 0x00))
+    if OutputBatchFile:
+        with open(OutputBatchFile, 'w') as FdOut:
+            if sys.platform.startswith('win'):
+                Id_Str = 'SET BIOS_ID=' + Id_Str
+            else:
+                Id_Str = 'export BIOS_ID=' + Id_Str
+            FdOut.write(Id_Str)
+    return 0
+
+if __name__ == '__main__':
+    r = Main()
+    ## 0-127 is a safe return range, and 1 is a standard default error
+    if r < 0 or r > 127: r = 1
+    sys.exit(r)
-- 
2.18.0.windows.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-06-14 15:06 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-05-28  1:32 [PATCH] BaseTools/GenBiosId: Add a new tool GenBiosId Zhang, Shenglei
2019-05-28 16:48 ` [edk2-devel] " Michael D Kinney
2019-05-31  6:36   ` Zhang, Shenglei
  -- strict thread matches above, loose matches on Subject: below --
2019-06-14  7:38 Zhang, Shenglei
2019-06-14 15:06 ` [edk2-devel] " Michael D Kinney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox