From 0bae1b9d0f250bea887d930ecc8da99986fab463 Mon Sep 17 00:00:00 2001 From: Mike Jones Date: Tue, 10 Apr 2012 16:01:57 -0500 Subject: HWPF: Use fixed enum values for generated error/attr enums Change-Id: Id0552daad9e6d9907cef7fa013fc6d75dbc8e185 RTC: 39175 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/879 Tested-by: Jenkins Server Reviewed-by: Van H. Lee Reviewed-by: CAMVAN T. NGUYEN Reviewed-by: Brian H. Horton Reviewed-by: A. Patrick Williams III --- src/usr/hwpf/fapi/fapiParseAttributeInfo.pl | 48 ++++++++++++------ src/usr/hwpf/fapi/fapiParseErrorInfo.pl | 36 ++++++++++++-- src/usr/hwpf/ifcompiler/initSymbols.C | 77 +++++++++++------------------ src/usr/hwpf/ifcompiler/initSymbols.H | 8 +-- 4 files changed, 96 insertions(+), 73 deletions(-) diff --git a/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl b/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl index 0dde39376..54349fadd 100755 --- a/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl +++ b/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl @@ -52,6 +52,7 @@ # mjjones 12/16/11 Generate fapiAttributePlatCheck.H # Generate fapiAttributesSupported.html # mjjones 02/08/12 Handle attribute files with 1 entry +# mjjones 03/22/12 Generate hash values for enums # # End Change Log ****************************************************** @@ -75,12 +76,20 @@ if ($numArgs < 2) #------------------------------------------------------------------------------ # Specify perl modules to use #------------------------------------------------------------------------------ +use Digest::MD5 qw(md5_hex); use XML::Simple; my $xml = new XML::Simple (KeyAttr=>[]); # Uncomment to enable debug output #use Data::Dumper; +#------------------------------------------------------------------------------ +# Set PREFERRED_PARSER to XML::Parser. Otherwise it uses XML::SAX which contains +# bugs that result in XML parse errors that can be fixed by adjusting white- +# space (i.e. parse errors that do not make sense). +#------------------------------------------------------------------------------ +$XML::Simple::PREFERRED_PARSER = 'XML::Parser'; + #------------------------------------------------------------------------------ # Open output files for writing #------------------------------------------------------------------------------ @@ -146,6 +155,7 @@ my $attribute = 'attribute'; foreach my $argnum (1 .. $#ARGV) { my $infile = $ARGV[$argnum]; + my %enumHash; # read XML file. The ForceArray option ensures that there is an array of # attributes even if there is only one attribute in the file @@ -160,7 +170,15 @@ foreach my $argnum (1 .. $#ARGV) foreach my $attr (@{$attributes->{attribute}}) { #---------------------------------------------------------------------- - # Print the AttributeId to fapiAttributeIds.H + # Print the AttributeId enum to fapiAttributeIds.H + # The enumerator value for each attribute is a hash value generated + # from the attribute name, this ties a specific enumerator value to a + # specific attribute name. This is done for Cronus so that if a HWP is + # not recompiled against a new eCMD/Cronus version where the attributes + # have changed then there will not be a mismatch in enumerator values. + # This is a 28bit hash value because the Initfile compiler has a + # requirement that the top nibble of the 32 bit attribute ID be zero to + # store flags #---------------------------------------------------------------------- if (! exists $attr->{id}) { @@ -168,7 +186,19 @@ foreach my $argnum (1 .. $#ARGV) exit(1); } - print AIFILE " $attr->{id},\n"; + # Calculate a 28 bit hash value. + my $attrHash128Bit = md5_hex($attr->{id}); + my $attrHash28Bit = substr($attrHash128Bit, 0, 7); + print AIFILE " $attr->{id} = 0x$attrHash28Bit,\n"; + + if (exists($enumHash{$attrHash28Bit})) + { + # Two different attributes generate the same hash-value! + print ("fapiParseAttributeInfo.pl ERROR. Duplicate attr id hash value\n"); + exit(1); + } + + $enumHash{$attrHash28Bit} = 1; }; } @@ -198,8 +228,6 @@ foreach my $argnum (1 .. $#ARGV) #-------------------------------------------------------------------------- # For each Attribute #-------------------------------------------------------------------------- - my $attCount = 0; - foreach my $attr (@{$attributes->{attribute}}) { #---------------------------------------------------------------------- @@ -272,18 +300,6 @@ foreach my $argnum (1 .. $#ARGV) exit(1); } - #---------------------------------------------------------------------- - # Print if the platform initializes the value to fapiAttributeIds.H - #---------------------------------------------------------------------- - if (exists $attr->{platInit}) - { - print AIFILE "#define $attr->{id}_PLATINIT true\n" - } - else - { - print AIFILE "#define $attr->{id}_PLATINIT false\n" - } - #---------------------------------------------------------------------- # Print the value enumeration (if specified) to fapiAttributeIds.H #---------------------------------------------------------------------- diff --git a/src/usr/hwpf/fapi/fapiParseErrorInfo.pl b/src/usr/hwpf/fapi/fapiParseErrorInfo.pl index 0aacea269..87a4cd12d 100755 --- a/src/usr/hwpf/fapi/fapiParseErrorInfo.pl +++ b/src/usr/hwpf/fapi/fapiParseErrorInfo.pl @@ -45,6 +45,7 @@ # camvanng 10/20/11 Fix bug # mjjones 12/16/11 Improved usage statement # mjjones 02/10/12 Allow err file with one element +# mjjones 03/22/12 Generate hash values for enums # # End Change Log ****************************************************** @@ -54,6 +55,13 @@ use strict; +#------------------------------------------------------------------------------ +# Set PREFERRED_PARSER to XML::Parser. Otherwise it uses XML::SAX which contains +# bugs that result in XML parse errors that can be fixed by adjusting white- +# space (i.e. parse errors that do not make sense). +#------------------------------------------------------------------------------ +$XML::Simple::PREFERRED_PARSER = 'XML::Parser'; + #------------------------------------------------------------------------------ # Subroutine that checks if an entry exists in an array. If it doesn't exist # then it is added. The index of the entry within the array is returned @@ -104,6 +112,7 @@ if ($numArgs < 2) #------------------------------------------------------------------------------ # Specify perl modules to use #------------------------------------------------------------------------------ +use Digest::MD5 qw(md5_hex); use XML::Simple; my $xml = new XML::Simple (KeyAttr=>[]); @@ -137,7 +146,6 @@ print RCFILE " * \@brief Enumeration of HWP return codes\n"; print RCFILE " *\/\n"; print RCFILE "enum HwpReturnCode\n"; print RCFILE "{\n"; -print RCFILE " RC_SUCCESS = 0,\n"; #------------------------------------------------------------------------------ # Print start of file information to fapiHwpErrorInfo.H @@ -163,11 +171,11 @@ my $gard = 'gard'; #------------------------------------------------------------------------------ # For each XML file #------------------------------------------------------------------------------ -my $errId = 1; foreach my $argnum (1 .. $#ARGV) { my $infile = $ARGV[$argnum]; my $count = 0; + my %enumHash; #-------------------------------------------------------------------------- # Read XML file. The ForceArray option ensures that there is an array of @@ -200,10 +208,28 @@ foreach my $argnum (1 .. $#ARGV) } #---------------------------------------------------------------------- - # Print the return code to fapiHwpReturnCodes.H + # Print the return code enum to fapiHwpReturnCodes.H + # The enumerator value for each error is a hash value generated from + # the errpr name, this ties a specific enumerator value to a specific + # error name. This is done for Cronus so that if a HWP is not + # recompiled against a new eCMD/Cronus version where the errors have + # changed then there will not be a mismatch in enumerator values. + # This is a 24bit hash value because FAPI has a requirement that the + # top byte of the 32 bit error value be zero to store flags indicating + # the creator of the error #---------------------------------------------------------------------- - print RCFILE " $err->{rc} = $errId,\n"; - $errId++; + my $attrHash128Bit = md5_hex($err->{rc}); + my $attrHash24Bit = substr($attrHash128Bit, 0, 6); + print RCFILE " $err->{rc} = 0x$attrHash24Bit,\n"; + + if (exists($enumHash{$attrHash24Bit})) + { + # Two different errors generate the same hash-value! + print ("fapiParseAttributeInfo.pl ERROR. Duplicate error rc hash value\n"); + exit(1); + } + + $enumHash{$attrHash24Bit} = 1; #---------------------------------------------------------------------- # Print the CALL_FUNC_TO_ANALYZE_ERROR macro to fapiHwpErrorInfo.H diff --git a/src/usr/hwpf/ifcompiler/initSymbols.C b/src/usr/hwpf/ifcompiler/initSymbols.C index 68e18f01c..f2cb9c2c7 100755 --- a/src/usr/hwpf/ifcompiler/initSymbols.C +++ b/src/usr/hwpf/ifcompiler/initSymbols.C @@ -24,6 +24,7 @@ // mjjones 11/17/11 Output attribute listing // camvanng 11/17/11 Support for system & target attributes // camvanng 01/07/12 Support for writing an attribute to a SCOM register +// camvanng 04/10/12 Support fixed attribute enum value // End Change Log ********************************************************************************* /** @@ -85,45 +86,30 @@ Symbols::Symbols(FILELIST & i_filenames) getline(infs,fileline); getline(infs,fileline); - // We're just parsing the enum in order so attribute id start - // at 0 and increment by 1 after that. - uint32_t attrId = 0; - while(fileline[0] != '}') { istringstream attr_stream(fileline); string attr; + char tempChar = 0; + uint32_t attrId = 0; + + // Read the attribute name attr_stream >> attr; - // Strip off the "," at the end. - size_t pos = attr.find(','); - if(pos != string::npos) - { - attr = attr.substr(0,attr.length()-1); - } + // Read and ignore the '=' '0' 'x' characters + attr_stream >> tempChar; + attr_stream >> tempChar; + attr_stream >> tempChar; - //printf("Attribute String:%s\n",attr.c_str()); - // We now have the first attribute loaded into attr - // Get an index for the string + // Read the attribute ID + attr_stream >> hex >> attrId; + // Store the value iv_symbols[attr] = MAP_DATA(attrId,NOT_USED); + iv_symbols[SYS_ATTR + attr] = MAP_DATA(attrId,NOT_USED); - attrId++; getline(infs,fileline); } - - //Create system attribute for each of the attribute found - //Assign them unique attribute ids - SYMBOL_MAP::iterator itr = iv_symbols.begin(); - uint32_t size = iv_symbols.size(); - for(uint32_t j = 0; j < size; ++j) - { - string sysAttr = SYS_ATTR + (*itr).first; - //printf("\n\n\nsysAttr %s", sysAttr.c_str()); - iv_symbols[sysAttr] = MAP_DATA(attrId,NOT_USED); - attrId++; - itr++; - } } else { @@ -388,7 +374,6 @@ uint32_t Symbols::add_undefined(const string & i_symbol) uint16_t Symbols::get_tag(uint32_t i_rpn_id) { uint16_t tag = NOT_FOUND; - uint32_t cini_id = CINI_ID_NOT_FOUND; // Set up tag table if not already setup if(iv_used_var.size() == 0) @@ -405,13 +390,18 @@ uint16_t Symbols::get_tag(uint32_t i_rpn_id) { if(i->second.second != NOT_USED) { + //printf("Symbols::get_tag adding rpn_id[0x%x]\n", i->second.second); + if((i->second.first & CINI_LIT_MASK) == CINI_LIT_MASK) { iv_used_lit.push_back(i->second.first); + //printf("Symbols::get_tag added to iv_used_lit[0x%x]\n", iv_used_lit.back()); } else //VAR { - iv_used_var.push_back(RPN_DATA(find_text(i->second.first), i->second.first)); + iv_used_var.push_back(RPN_DATA(i->first, i->second.first)); + //printf("Symbols::get_tag added to iv_used_var[%s, 0x%x]\n", + // iv_used_var.back().first.c_str(), iv_used_var.back().second); } } } @@ -419,12 +409,8 @@ uint16_t Symbols::get_tag(uint32_t i_rpn_id) do { - RPN_MAP::iterator rm = iv_rpn_map.find(i_rpn_id); - if(rm != iv_rpn_map.end()) - { - cini_id = (rm->second).second; - } - else + string name = find_name(i_rpn_id); + if ("NOT_FOUND" == name) { //SYMBOL_MAP::iterator sm = iv_not_found.begin(); //for(; sm != iv_not_found.end(); ++sm) @@ -448,14 +434,14 @@ uint16_t Symbols::get_tag(uint32_t i_rpn_id) uint32_t offset = 0; for(VAR_SYMBOL_USED::iterator i = iv_used_var.begin(); i != iv_used_var.end(); ++i,++offset) { - if(cini_id == (*i).second) + if (name == (*i).first) { tag = (uint16_t) (offset | IF_ATTR_TYPE); - if ((*i).first.compare(0, 4, SYS_ATTR) == 0) + if (name.compare(0, 4, SYS_ATTR) == 0) { tag |= IF_SYS_ATTR_MASK; - //printf ("get tag: %s tag 0x%x\n", (*i).first.c_str(), tag); + //printf ("get tag: %s tag 0x%x\n", name.c_str(), tag); } break; @@ -606,6 +592,8 @@ string Symbols::find_text(uint32_t i_cini_id) else if(i_cini_id == SYM_EXPR) name = "EXPR"; else { + //NOTE: if there are multiple elements of the same cini_id, then this function will return the + //first element found for(SYMBOL_MAP::const_iterator i = iv_symbols.begin(); i != iv_symbols.end(); ++i) { //printf("SYMBOL:%s\n",i->first.c_str()); @@ -873,16 +861,10 @@ uint32_t Symbols::bin_vars(BINSEQ & blist) string name = (*i).first; uint32_t attrId = (*i).second; - // If sys attribute, use same attribute id as target attribute - if (name.compare(0, 4, SYS_ATTR) == 0) - { - attrId = iv_symbols[name.substr(4)].first; - } - Rpn::set8(blist,iv_attr_type[name]); Rpn::set32(blist,attrId); - //printf("Symbols::bin_vars: Just wrote out type:%u index:%u\n",iv_attr_type[name],attrId); + //printf("Symbols::bin_vars: Just wrote out type:%u attrId:0x%x\n",iv_attr_type[name],attrId); } return count; } @@ -1034,13 +1016,12 @@ uint32_t Symbols::get_rpn_id(uint32_t bin_tag) uint32_t rpn_id = NOT_FOUND; uint32_t type = bin_tag & IF_TYPE_MASK; uint32_t offset = bin_tag & ~IF_TYPE_MASK; - uint32_t cini_id = 0; + //uint32_t cini_id = 0; switch(type) { case IF_ATTR_TYPE: { offset &= ~IF_SYS_ATTR_MASK; - cini_id = iv_used_var[offset].second; - string name = find_text(cini_id); + string name = iv_used_var[offset].first; rpn_id = use_symbol(name); } break; diff --git a/src/usr/hwpf/ifcompiler/initSymbols.H b/src/usr/hwpf/ifcompiler/initSymbols.H index dc77a9425..d3b957ebb 100755 --- a/src/usr/hwpf/ifcompiler/initSymbols.H +++ b/src/usr/hwpf/ifcompiler/initSymbols.H @@ -236,8 +236,8 @@ namespace init private: //data // map | symbol name | (cini_id, usage flags) | - typedef pair MAP_DATA; - typedef map SYMBOL_MAP; + typedef pair MAP_DATA; //cini_id & corresponding rpn_id/NOT_USED + typedef map SYMBOL_MAP; //attr name & corresponding cini_id, rpn_id/NOT_USED pair typedef map SPY_MAP; typedef map SYMBOL_ATTR_TYPE; typedef map SYMBOL_ATTR_ENUM; @@ -245,8 +245,8 @@ namespace init typedef pair DEF_DATA; typedef map DEF_MAP; - typedef pair RPN_DATA; - typedef map RPN_MAP; + typedef pair RPN_DATA; //attribute name & corresponding cini_id + typedef map RPN_MAP; //attr name & corresponding attr name, cini_id pair typedef vector VAR_SYMBOL_USED; typedef vector SYMBOL_USED; -- cgit v1.2.1