Home | History | Annotate | Download | only in Scripts
      1 ## @file

      2 # Convert a binary file to a VOID* PCD value or DSC file VOID* PCD statement.

      3 #

      4 # Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>

      5 # This program and the accompanying materials

      6 # are licensed and made available under the terms and conditions of the BSD License

      7 # which accompanies this distribution.  The full text of the license may be found at

      8 # http://opensource.org/licenses/bsd-license.php

      9 #

     10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

     11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

     12 #

     13 
     14 '''
     15 BinToPcd
     16 '''
     17 
     18 import sys
     19 import argparse
     20 import re
     21 
     22 #

     23 # Globals for help information

     24 #

     25 __prog__        = 'BinToPcd'
     26 __version__     = '%s Version %s' % (__prog__, '0.9 ')
     27 __copyright__   = 'Copyright (c) 2016, Intel Corporation. All rights reserved.'
     28 __description__ = 'Convert a binary file to a VOID* PCD value or DSC file VOID* PCD statement.\n'
     29 
     30 if __name__ == '__main__':
     31   def ValidateUnsignedInteger (Argument):
     32     try:
     33       Value = int (Argument, 0)
     34     except:
     35       Message = '%s is not a valid integer value.' % (Argument)
     36       raise argparse.ArgumentTypeError(Message)
     37     if Value < 0:
     38       Message = '%s is a negative value.' % (Argument)
     39       raise argparse.ArgumentTypeError(Message)
     40     return Value
     41 
     42   def ValidatePcdName (Argument):
     43     if re.split('[a-zA-Z\_][a-zA-Z0-9\_]*\.[a-zA-Z\_][a-zA-Z0-9\_]*', Argument) <> ['','']:
     44       Message = '%s is not in the form <PcdTokenSpaceGuidCName>.<PcdCName>' % (Argument)
     45       raise argparse.ArgumentTypeError(Message)
     46     return Argument
     47 
     48   def ValidateGuidName (Argument):
     49     if re.split('[a-zA-Z\_][a-zA-Z0-9\_]*', Argument) <> ['','']:
     50       Message = '%s is not a valid GUID C name' % (Argument)
     51       raise argparse.ArgumentTypeError(Message)
     52     return Argument
     53     
     54   def ByteArray (Buffer):
     55     #

     56     # Append byte array of values of the form '{0x01, 0x02, ...}'

     57     #

     58     return '{%s}' % (', '.join(['0x%02x' % (ord(Item)) for Item in Buffer]))
     59     
     60   #

     61   # Create command line argument parser object

     62   #

     63   parser = argparse.ArgumentParser(prog = __prog__, version = __version__,
     64                                    description = __description__ + __copyright__,
     65                                    conflict_handler = 'resolve')
     66   parser.add_argument("-i", "--input", dest = 'InputFile', type = argparse.FileType('rb'),
     67                       help = "Input binary filename", required = True)
     68   parser.add_argument("-o", "--output", dest = 'OutputFile', type = argparse.FileType('wb'),
     69                       help = "Output filename for PCD value or PCD statement")
     70   parser.add_argument("-p", "--pcd", dest = 'PcdName', type = ValidatePcdName,
     71                       help = "Name of the PCD in the form <PcdTokenSpaceGuidCName>.<PcdCName>")
     72   parser.add_argument("-t", "--type", dest = 'PcdType', default = None, choices = ['VPD','HII'],
     73                       help = "PCD statement type (HII or VPD).  Default is standard.")
     74   parser.add_argument("-m", "--max-size", dest = 'MaxSize', type = ValidateUnsignedInteger,
     75                       help = "Maximum size of the PCD.  Ignored with --type HII.")
     76   parser.add_argument("-f", "--offset", dest = 'Offset', type = ValidateUnsignedInteger,
     77                       help = "VPD offset if --type is VPD.  UEFI Variable offset if --type is HII.")
     78   parser.add_argument("-n", "--variable-name", dest = 'VariableName',
     79                       help = "UEFI variable name.  Only used with --type HII.")
     80   parser.add_argument("-g", "--variable-guid", type = ValidateGuidName, dest = 'VariableGuid',
     81                       help = "UEFI variable GUID C name.  Only used with --type HII.")
     82   parser.add_argument("-v", "--verbose", dest = 'Verbose', action = "store_true",
     83                       help = "Increase output messages")
     84   parser.add_argument("-q", "--quiet", dest = 'Quiet', action = "store_true",
     85                       help = "Reduce output messages")
     86   parser.add_argument("--debug", dest = 'Debug', type = int, metavar = '[0-9]', choices = range(0,10), default = 0,
     87                       help = "Set debug level")
     88 
     89   #

     90   # Parse command line arguments

     91   #

     92   args = parser.parse_args()
     93 
     94   #

     95   # Read binary input file

     96   #

     97   try:
     98     Buffer = args.InputFile.read()
     99     args.InputFile.close()
    100   except:
    101     print 'BinToPcd: error: can not read binary input file'
    102     sys.exit()
    103 
    104   #

    105   # Convert binary buffer to a DSC file PCD statement

    106   #

    107   if args.PcdName is None:
    108     #

    109     # If PcdName is None, then only a PCD value is being requested.

    110     Pcd = ByteArray (Buffer)
    111     if args.Verbose:
    112       print 'PcdToBin: Convert binary file to PCD Value'
    113   elif args.PcdType is None:
    114     #

    115     # If --type is neither VPD nor HII, then use PCD statement syntax that is

    116     # compatible with [PcdsFixedAtBuild], [PcdsPatchableInModule],

    117     # [PcdsDynamicDefault], and [PcdsDynamicExDefault].

    118     #

    119     if args.MaxSize is None:
    120       #

    121       # If --max-size is not provided, then do not generate the syntax that

    122       # includes the maximum size.

    123       #

    124       Pcd = '  %s|%s' % (args.PcdName, ByteArray (Buffer))
    125     elif args.MaxSize < len(Buffer):
    126       print 'BinToPcd: error: argument --max-size is smaller than input file.'
    127       sys.exit()
    128     else:
    129       Pcd = '  %s|%s|VOID*|%d' % (args.PcdName, ByteArray (Buffer), args.MaxSize)
    130       args.MaxSize = len(Buffer)
    131     
    132     if args.Verbose:
    133       print 'PcdToBin: Convert binary file to PCD statement compatible with PCD sections:'
    134       print '    [PcdsFixedAtBuild]'
    135       print '    [PcdsPatchableInModule]'
    136       print '    [PcdsDynamicDefault]'
    137       print '    [PcdsDynamicExDefault]'
    138   elif args.PcdType == 'VPD':
    139     if args.MaxSize is None:
    140       #

    141       # If --max-size is not provided, then set maximum size to the size of the

    142       # binary input file

    143       #

    144       args.MaxSize = len(Buffer)
    145     if args.MaxSize < len(Buffer):
    146       print 'BinToPcd: error: argument --max-size is smaller than input file.'
    147       sys.exit()
    148     if args.Offset is None:
    149       #

    150       # if --offset is not provided, then set offset field to '*' so build

    151       # tools will compute offset of PCD in VPD region.

    152       #

    153       Pcd = '  %s|*|%d|%s' % (args.PcdName, args.MaxSize, ByteArray (Buffer))
    154     else:
    155       #

    156       # Use the --offset value provided.

    157       #

    158       Pcd = '  %s|%d|%d|%s' % (args.PcdName, args.Offset, args.MaxSize, ByteArray (Buffer))
    159     if args.Verbose:
    160       print 'PcdToBin: Convert binary file to PCD statement compatible with PCD sections'
    161       print '    [PcdsDynamicVpd]'
    162       print '    [PcdsDynamicExVpd]'
    163   elif args.PcdType == 'HII':
    164     if args.VariableGuid is None:
    165       print 'BinToPcd: error: argument --variable-guid is required for --type HII.'
    166       sys.exit()
    167     if args.VariableName is None:
    168       print 'BinToPcd: error: argument --variable-name is required for --type HII.'
    169       sys.exit()
    170     if args.Offset is None:
    171       #

    172       # Use UEFI Variable offset of 0 if --offset is not provided

    173       #

    174       args.Offset = 0
    175     Pcd = '  %s|L"%s"|%s|%d|%s' % (args.PcdName, args.VariableName, args.VariableGuid, args.Offset, ByteArray (Buffer))
    176     if args.Verbose:
    177       print 'PcdToBin: Convert binary file to PCD statement compatible with PCD sections'
    178       print '    [PcdsDynamicHii]'
    179       print '    [PcdsDynamicExHii]'
    180 
    181   #

    182   # Write PCD value or PCD statement to the output file

    183   #

    184   try:
    185     args.OutputFile.write (Pcd)
    186     args.OutputFile.close ()
    187   except:
    188     #

    189     # If output file is not specified or it can not be written, then write the

    190     # PCD value or PCD statement to the console

    191     #

    192     print Pcd
    193