Home | History | Annotate | Download | only in generator
      1 #!/bin/sh
      2 # Copyright 2015 The Chromium OS Authors. All rights reserved.
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 # Pull out basic typdefs.
      7 cat $1 |
      8   # Mark types tables and section boundaries.
      9   sed 's/^[0-9][0-9]*\([.][0-9][0-9]*\)\+.*$/_SECTION_BOUNDARY/' |
     10   sed 's/^Table [0-9]* . Definition of .*Types[^.]*$/_TYPES/' |
     11   # Keep only table sections.
     12   awk '/^_TYPES$/,/^_SECTION_BOUNDARY$/ { print $0; }' |
     13   sed 's/^_TYPES$//' |
     14   sed 's/^_SECTION_BOUNDARY$//' |
     15   # Remove headers and footers.
     16   sed 's/^.*Trusted Platform Module Library.*$//' |
     17   sed 's/^.*Part 2: Structures.*$//' |
     18   sed 's/^.*Family .2.0..*$//' |
     19   sed 's/^.*Level 00 Revision.*$//' |
     20   sed 's/^.*Published.*$//' |
     21   sed 's/^.*Copyright.*$//' |
     22   sed 's/^.*Page [0-9].*$//' |
     23   sed 's/^.*October 31, 2013.*$//' |
     24   # Remove table headers.
     25   sed 's/^Type$//' | sed 's/^Name$//' | sed 's/^Description$//' |
     26   # Remove leading spaces.
     27   sed 's/^[ ][ ]*//' |
     28   # Remove empty lines.
     29   sed '/^$/d' |
     30   # Mark begin and end and filter types.
     31   awk '
     32     BEGIN { print "_BEGIN_TYPES"; state = 0; }
     33     /^[^ ]*$/ { if (!state) { print "_OLD_TYPE " $0; state = 1; }
     34                 else { print "_NEW_TYPE " $0; state = 0; } }
     35     END { print "_END"; }
     36   ' |
     37   # Sanity check.  The format should now follow this grammar:
     38   # Format:Begin||Typedef*||End
     39   # Begin:_BEGIN_TYPES\n
     40   # End:_END\n
     41   # Typedef:OldType||NewType
     42   # OldType:_OLD_TYPE <type>\n
     43   # NewType:_NEW_TYPE <type>\n
     44   awk '
     45     BEGIN { RS = ""; }
     46     $0 !~ /_BEGIN_TYPES\n(_OLD_TYPE[^\n]*\n_NEW_TYPE[^\n]*\n)*_END/ {
     47       print "_ERROR: Format check failed."; }
     48     { print $0; }
     49   '
     50 
     51 # Pull out constant values.
     52 cat $1 |
     53   # Mark constants tables and section boundaries.
     54   sed 's/^[0-9][0-9]*\([.][0-9][0-9]*\)\+.*$/_SECTION_BOUNDARY/' |
     55   sed 's/^Table [0-9]* . Definition of \(.*\) Constants[^.]*$/_CONSTANTS \1/' |
     56   # Keep only table sections.
     57   awk '/^_CONSTANTS .*$/,/^_SECTION_BOUNDARY$/ { print $0; }' |
     58   sed 's/^_SECTION_BOUNDARY$//' |
     59   # Remove headers and footers.
     60   sed 's/^.*Trusted Platform Module Library.*$//' |
     61   sed 's/^.*Part 2: Structures.*$//' |
     62   sed 's/^.*Family .2.0..*$//' |
     63   sed 's/^.*Level 00 Revision.*$//' |
     64   sed 's/^.*Published.*$//' |
     65   sed 's/^.*Copyright.*$//' |
     66   sed 's/^.*Page [0-9].*$//' |
     67   sed 's/^.*October 31, 2013.*$//' |
     68   # Remove table headers.
     69   sed 's/^Name$//' | sed 's/^Value$//' | sed 's/^Comments$//' |
     70   # Remove leading spaces.
     71   sed 's/^[ ][ ]*//' |
     72   # Remove empty lines.
     73   sed '/^$/d' |
     74   # Mark begin and end.
     75   awk '
     76     BEGIN { print "_BEGIN_CONSTANTS"; }
     77     { print $0; }
     78     END { print "_END"; }
     79   ' |
     80   # Mark type.
     81   awk '
     82     BEGIN { FS = "[ ()]+"; }
     83     { print $0; }
     84     /^_CONSTANTS \(\w*\) .*$/ { print "_OLD_TYPE " $2;
     85                                 print "_NEW_TYPE " $NF; }
     86   ' |
     87   # Mark names and error return type.
     88   sed 's/^\(TPM_[_A-Z0-9a]*\)$/_NAME \1/' |
     89   sed 's/^\(TPM_CC_[_A-Z0-9a-z]*\)$/_NAME \1/' |
     90   sed 's/^\(RC_[_A-Z0-9]*\)$/_NAME \1/' |
     91   sed 's/^\(PT_[_A-Z0-9]*\)$/_NAME \1/' |
     92   sed 's/^\(HR_[_A-Z0-9]*\)$/_NAME \1/' |
     93   sed 's/^\([_A-Z0-9]*FIRST\)$/_NAME \1/' |
     94   sed 's/^\([_A-Z0-9]*LAST\)$/_NAME \1/' |
     95   sed 's/^\(PLATFORM_PERSISTENT\)$/_NAME \1/' |
     96   sed 's/^\(#TPM_RC[_A-Z0-9]*\)$/_RETURN \1/' |
     97   # Keep only names and return types
     98   awk '
     99     BEGIN { last_line_was_name = 0;
    100             return_defined = 1;
    101             FS = " |#"; }
    102     /^_BEGIN_CONSTANTS$/ { print $0; }
    103     /^_OLD_TYPE .*$/ { if (!return_defined) {  print "_RETURN TPM_RC_VALUE"; }
    104                        return_defined = 0;
    105                        print $0 }
    106     /^_NEW_TYPE .*$/ { print $0; }
    107     /^_NAME .*$/ { if (last_line_was_name) {
    108                      last_line_was_name = 0;
    109                      if ($0 !~ /[A-Z_0-9x +]*/) { print "_ERROR: Invalid value"; } }
    110                    else { last_line_was_name = 1; print $0; } }
    111     /^_RETURN .*$/ { print "_RETURN " $3;
    112                      return_defined = 1; }
    113     /^[^_].*$/   { if (last_line_was_name) {
    114                      last_line_was_name = 0;
    115                      if ($0 !~ /[A-Z_0-9x +]*/) { print "_ERROR: Invalid value"; } } }
    116     /^_END$/ { if (!return_defined) { print "_RETURN TPM_RC_VALUE"; }
    117                print $0; }
    118   ' |
    119   # Sanity check.  The format should now follow this grammar:
    120   # Format:Begin||TableBlock*||End
    121   # Begin:_BEGIN_CONSTANTS\n
    122   # End:_END\n
    123   # TableBlock:Typedef||Name*||Return
    124   # Name:_NAME <name>\n
    125   # Return:_RETURN <name>\n
    126   # Typedef:OldType||NewType
    127   # OldType:_OLD_TYPE <type>\n
    128   # NewType:_NEW_TYPE <type>\n
    129   awk '
    130     BEGIN { RS = ""; }
    131     $0 !~ /_BEGIN_CONSTANTS\n(_OLD_TYPE[^\n]*\n_NEW_TYPE[^\n]*\n(_NAME[^\n]*\n)*_RETURN[^\n]*\n)*_END/ {
    132       print "_ERROR: Format check failed."; }
    133     { print $0; }
    134   '
    135 
    136 # Pull out attribute structs.
    137 cat $1 |
    138   # Mark reserved bits.
    139   sed 's/^\([0-9]\+:\?[0-9]* Reserved\)$/_RESERVED \1/' |
    140   awk '
    141     BEGIN { print "_BEGIN_ATTRIBUTE_STRUCTS";
    142             FS = "[ ()]+|:";
    143             in_attribute = 0; }
    144     /^Table [0-9]* . Definition of \([A-Z_0-9]*\) TPM[A-Z_]* Bits[^.]*$/ {
    145       print "_OLD_TYPE " $6;
    146       print "_NEW_TYPE " $7;
    147       in_attribute = 1; }
    148     /^_RESERVED .*$/ { if (in_attribute && NF == 4) {
    149                          print "_RESERVED " $3 "_" $2; }
    150                        else if (in_attribute) {
    151                          print "_RESERVED " $2; } }
    152     END { print "_END"; }
    153   ' |
    154   # Sanity check.  The format should now follow this grammar:
    155   # Format:Begin||TableBlock*||End
    156   # Begin:_BEGIN_ATTRIBUTE_STRUCTS\n
    157   # End:_END\n
    158   # TableBlock:Typedef||Reserved*
    159   # Reserved:_RESERVED <value>(_<value>)?\n
    160   # Typedef:OldType||NewType
    161   # OldType:_OLD_TYPE <type>\n
    162   # NewType:_NEW_TYPE <type>\n
    163   awk '
    164     BEGIN { RS = ""; }
    165     $0 !~ /_BEGIN_ATTRIBUTE_STRUCTS\n(_OLD_TYPE[^\n]*\n_NEW_TYPE[^\n]*\n(_RESERVED[^\n]*\n)*)*_END/ {
    166       print "_ERROR: Format check failed."; }
    167     { print $0; }
    168   '
    169 
    170 # Pull out interface types.
    171 cat $1 |
    172   # Mark interface tables and section boundaries.
    173   sed 's/^[0-9][0-9]*\([.][0-9][0-9]*\)\+.*$/_SECTION_BOUNDARY/' |
    174   sed 's/^Table [0-9]* . Definition of \(.*\) Type[^.s]*$/_INTERFACES \1/' |
    175   # Keep only table sections.
    176   awk '/^_INTERFACES .*$/,/^_SECTION_BOUNDARY$/ { print $0; }' |
    177   sed 's/^_SECTION_BOUNDARY$//' |
    178   # Remove headers and footers.
    179   sed 's/^.*Trusted Platform Module Library.*$//' |
    180   sed 's/^.*Part 2: Structures.*$//' |
    181   sed 's/^.*Family .2.0..*$//' |
    182   sed 's/^.*Level 00 Revision.*$//' |
    183   sed 's/^.*Published.*$//' |
    184   sed 's/^.*Copyright.*$//' |
    185   sed 's/^.*Page [0-9].*$//' |
    186   sed 's/^.*October 31, 2013.*$//' |
    187   # Remove table headers.
    188   sed 's/^Type$//' | sed 's/^Name$//' | sed 's/^Description$//' |
    189   # Remove leading spaces.
    190   sed 's/^[ ][ ]*//' |
    191   # Remove empty lines.
    192   sed '/^$/d' |
    193   # Mark begin and end.
    194   awk '
    195     BEGIN { print "_BEGIN_INTERFACES"; }
    196     { print $0; }
    197     END { print "_END"; }
    198   ' |
    199   # Mark type.
    200   awk '
    201     BEGIN { FS = "[ ()]+"; }
    202     { print $0; }
    203     /^_INTERFACES \(\w*\) .*$/ { print "_OLD_TYPE " $2;
    204                                 print "_NEW_TYPE " $NF; }
    205     /^_INTERFACES {[A-Z0-9]*} \(\w*\) .*$/ { print "_OLD_TYPE " $3;
    206                                           print "_NEW_TYPE " $NF; }
    207   ' |
    208   # Mark names, bounds, conditional values, and return values.
    209   sed 's/^\(TPM_[_A-Z0-9a]*\)$/_NAME \1/' |
    210   sed 's/^\(TPM_CC_[_A-Z0-9a-z]*\)$/_NAME \1/' |
    211   sed 's/^\(RC_[_A-Z0-9]*\)$/_NAME \1/' |
    212   sed 's/^\(PT_[_A-Z0-9]*\)$/_NAME \1/' |
    213   sed 's/^\(HR_[_A-Z0-9]*\)$/_NAME \1/' |
    214   sed 's/^\([_A-Z0-9]*FIRST\)$/_NAME \1/' |
    215   sed 's/^\([_A-Z0-9]*LAST\)$/_NAME \1/' |
    216   sed 's/^\(PLATFORM_PERSISTENT\)$/_NAME \1/' |
    217   sed 's/^\(NO\)$/_NAME \1/' |
    218   sed 's/^\(YES\)$/_NAME \1/' |
    219   sed 's/^\({[_A-Z0-9]*:[_A-Z0-9]*}\)$/_BOUND \1/' |
    220   sed 's/^\(+[_A-Z0-9]*\)$/_CONDITIONAL \1/' |
    221   sed 's/^\(#TPM_RC[_A-Z0-9]*\)$/_RETURN \1/' |
    222   sed 's/^\(\$.*\)$/_SUBSTITUTE \1/' |
    223   awk '
    224     BEGIN { print "_BEGIN_INTERFACES";
    225             FS = " |:|{|}|#|+";
    226             ret = 1; }
    227     /^_OLD_TYPE .*$/ { if (!ret) { print "_RETURN TPM_RC_VALUE"; }
    228                        ret = 0; }
    229     /^_.*_TYPE .*$/ { print $0; }
    230     /^_NAME .*$/ { print $0; }
    231     /^_SUBSTITUTE .*$/ { $2 = substr($2, 2, length($2)-1);
    232                          print $0; }
    233     /^_BOUND .*$/ { print "_MIN " $3;
    234                     print "_MAX " $4; }
    235     /^_CONDITIONAL .*$/ { print "_CONDITIONAL " $3; }
    236     /^_RETURN .*$/ { print "_RETURN " $3;
    237                      ret = 1; }
    238     END { print "_END"; }
    239   ' |
    240   # Sanity check.  The format should now follow this grammar:
    241   # Format:Begin||Tableblock*||End
    242   # Begin:_BEGIN_INTERFACES\n
    243   # End:_END\n
    244   # Tableblock: Typedef||(Subval?|Name*)||Bound*||Conditional?||Return
    245   # Name:_NAME <name>\n
    246   # Subval:_SUBSTITUTE <name>\n
    247   # Bound:Min||Max
    248   # Min:_MIN <name>\n
    249   # Max:_MAX <name>\n
    250   # Conditional:_CONDITIONAL <name>\n
    251   # Return:_RETURN <name>\n
    252   # Typedef:OldType||NewType
    253   # OldType:_OLD_TYPE <type>\n
    254   # NewType:_NEW_TYPE <type>\n
    255   awk '
    256     BEGIN { RS = ""; }
    257     $0 !~ /_BEGIN_INTERFACES\n(_OLD_TYPE[^\n]*\n_NEW_TYPE[^\n]*\n(_NAME[^\n]*\n)*(_SUBSTITUTE[^\n]*\n)?(_MIN[^\n]*\n_MAX[^\n]*\n)*(_CONDITIONAL[^\n]*\n)?(_RETURN[^\n]*\n)?)*_END/ {
    258       print "_ERROR: Format check failed."; }
    259     { print $0; }
    260   '
    261 # Pull out structures.
    262 cat $1 |
    263   # Mark tables and section boundaries.
    264   sed 's/^[0-9][0-9]*\([.][0-9][0-9]*\)\+.*$/_SECTION_BOUNDARY/' |
    265   sed 's/^Table [0-9]* . Definition of \(.*\) Structure[^.]*$/_STRUCTURE \1/' |
    266   # Keep only table sections.
    267   awk '/^_STRUCTURE .*$/,/^_SECTION_BOUNDARY$/ { print $0; }' |
    268   sed 's/^_SECTION_BOUNDARY$//' |
    269   # Remove headers and footers.
    270   sed 's/^.*Trusted Platform Module Library.*$//' |
    271   sed 's/^.*Part 2: Structures.*$//' |
    272   sed 's/^.*Family .2.0..*$//' |
    273   sed 's/^.*Level 00 Revision.*$//' |
    274   sed 's/^.*Published.*$//' |
    275   sed 's/^.*Copyright.*$//' |
    276   sed 's/^.*Page [0-9].*$//' |
    277   sed 's/^.*October 31, 2013.*$//' |
    278   # Remove table headers.
    279   sed 's/^Parameter$//' | sed 's/^Type$//' | sed 's/^Description$//' |
    280   # Remove leading spaces.
    281   sed 's/^[ ][ ]*//' |
    282   # Remove empty lines.
    283   sed '/^$/d' |
    284   # Mark begin and end.
    285   awk '
    286     BEGIN { print "_BEGIN_STRUCTURES"; }
    287     { print $0; }
    288     END { print "_END"; }
    289   ' |
    290   # Mark field types.
    291   sed 's/^\(+*TPM[_A-Z0-9+]*\)$/_TYPE \1/' |
    292   sed 's/^\(UINT[0-9]*\)$/_TYPE \1/' |
    293   sed 's/^\(BYTE*\)$/_TYPE \1/' |
    294   # Mark field names and associated decorations
    295   awk '
    296     BEGIN { last_line = "";
    297             FS = ":| |{|}|+|#"; }
    298     /^_.*$/      { if ($1 != "_TYPE") { print $0; } }
    299     /^_TYPE \+[A-Z0-9_]*$/ { print $1 " " $3;
    300                              prefix = substr($3, 1, 4);
    301                              if (last_line != "" && prefix == "TPMI") {
    302                                print "_NAME " last_line " _PLUS";
    303                              } else if (last_line != "") {
    304                                print "_NAME " last_line;
    305                              } else { print "_ERROR: Type with no name"; }
    306                              last_line = ""; }
    307     /^_TYPE [A-Z0-9_]*\+$/ { print $1 " " $2;
    308                              prefix = substr($2, 1, 4);
    309                              if (last_line != "" && prefix == "TPMI") {
    310                                print "_NAME " last_line " _PLUS";
    311                              } else if (last_line != "") {
    312                                print "_NAME " last_line;
    313                              } else { print "_ERROR: Type with no name"; }
    314                              last_line = ""; }
    315     /^_TYPE [A-Z0-9_]*$/ { print $0;
    316                            if (last_line != "") { print "_NAME " last_line ; }
    317                            else { print "_ERROR: Type with no name"; }
    318                            if (extra_line != "") { print extra_line; }
    319                            last_line = "";
    320                            extra_line = ""; }
    321     /^[^_].*$/   { last_line = $0; }
    322     /^\[[^]]*\].*$/ { $1 = substr($1, 2, length($1)-1);
    323                       sub(/\]/, " ", $0);
    324                       last_line = $2 " _UNION " $1; }
    325     /^.*\[[^]]*\]$/ { $1 = substr($1, 1, length($1)-1);
    326                       sub(/\]/, " " , $0);
    327                       last_line = $1 " _ARRAY " $2; }
    328     /^.*\{[A-Z0-9_]*:\}$/ { last_line = $1;
    329                             extra_line = "_MIN " $1 " " $3; }
    330     /^.*\{:[A-Z0-9_]*\}$/ { last_line = $1;
    331                             extra_line = "_MAX " $1 " " $3; }
    332     /^.*\[[^]]*\] \{:[a-zA-Z0-9_()\/]*\}$/ { $2 = substr($2, 2, length($2)-2);
    333                                    last_line = $1 " _ARRAY " $2;
    334                                    extra_line = "_MAX " $2 " " $5 ; }
    335     /^tag \{[A-Z_]*(, [A-Z_]*)*\}$/ { last_line = "tag";
    336                                       extra_line = "_VALID " $3;
    337                                       for (i = 4; i <= NF-1; i++)
    338                                         extra_line = extra_line "\n_VALID " $i;
    339                                       sub(/\,/, "", extra_line); }
    340     /^size\=$/ { last_line = "size _CHECK" }
    341     /^#.*$/ { print "_RETURN " $2; }
    342   ' |
    343   # Strip off structure modifiers
    344   sed 's/^_STRUCTURE \((.*) \)*{.*} \(.*\)/_STRUCTURE \2/' |
    345   # Sanity check.  The format should now follow this grammar:
    346   # Format:Begin||Tableblock*||End
    347   # Begin:_BEGIN_STRUCTURES\n
    348   # End:_END\n
    349   # Tableblock: Structure||(Field|Min|Max)*||Return?
    350   # Structure:_STRUCTURE <name>\n
    351   # Min:_MIN <name> <value>\n
    352   # Max:_Max <name> <value>\n
    353   # Return:_RETURN <name>\n
    354   # Field: Type||Name||Valid*
    355   # Type:_TYPE <name>\n
    356   # Valid:_VALID <value>\n
    357   # Name:_NAME <name>((( _UNION | _ARRAY )<value>)| _PLUS)?\n
    358   # No sanity check here. Format is checked during generator.py
    359   awk '
    360     { print $0; }
    361   '
    362 
    363 # Pull out unions.
    364 cat $1 |
    365   # Mark tables and section boundaries.
    366   sed 's/^[0-9][0-9]*\([.][0-9][0-9]*\)\+.*$/_SECTION_BOUNDARY/' |
    367   sed 's/^Table [0-9]* . Definition of \(.*\) Union[^.]*$/_UNION \1/' |
    368   # Keep only table sections.
    369   awk '/^_UNION .*$/,/^_SECTION_BOUNDARY$/ { print $0; }' |
    370   sed 's/^_SECTION_BOUNDARY$//' |
    371   # Remove headers and footers.
    372   sed 's/^.*Trusted Platform Module Library.*$//' |
    373   sed 's/^.*Part 2: Structures.*$//' |
    374   sed 's/^.*Family .2.0..*$//' |
    375   sed 's/^.*Level 00 Revision.*$//' |
    376   sed 's/^.*Published.*$//' |
    377   sed 's/^.*Copyright.*$//' |
    378   sed 's/^.*Page [0-9].*$//' |
    379   sed 's/^.*October 31, 2013.*$//' |
    380   # Remove table headers.
    381   sed 's/^Parameter$//' | sed 's/^Type$//' | sed 's/^Selector$//' |
    382   sed 's/^Description$//' |
    383   # Remove leading spaces.
    384   sed 's/^[ ][ ]*//' |
    385   # Remove empty lines.
    386   sed '/^$/d' |
    387   # Mark begin and end.
    388   awk '
    389     BEGIN { print "_BEGIN_UNIONS"; }
    390     { print $0; }
    391     END { print "_END"; }
    392   ' |
    393   # Mark field types.
    394   sed 's/^\(+*TPM[_A-Z0-9+a]*\)$/_TYPE \1/' |
    395   sed 's/^\(UINT[0-9]*\)$/_TYPE \1/' |
    396   sed 's/^\(BYTE*\)$/_TYPE \1/' |
    397   # Mark field names and throw away everything else.
    398   awk '
    399     BEGIN { last_line = ""; }
    400     /^_.*$/      { if ($0 !~ /^_TYPE .*$/) { last_line = ""; print $0; } }
    401     /^_TYPE .*$/ { if (last_line !~ /^_TYPE .*$/) {
    402                      if (last_line != "" &&
    403                          last_line != "null" &&
    404                          last_line != "NOTE") {
    405                        print $0;
    406                        print "_NAME " last_line; }
    407                      else if (last_line == "") {
    408                        print "_ERROR: Type with no name"; }
    409                      last_line = $0; } }
    410     /^[^_].*$/   { last_line = $0; }
    411     /^.* \[[^]]*\]$/ { $2 = substr($2, 2, length($2)-2);
    412                      last_line = $1 " _ARRAY " $2; }
    413   ' |
    414   # Sanity check.  The format should now follow this grammar:
    415   # Format:Begin||TableBlock*||End
    416   # Begin:_BEGIN_UNIONS\n
    417   # End:_END\n
    418   # TableBlock:TableTag||Field*
    419   # TableTag:_UNION <name>\n
    420   # Field:Type||Name
    421   # Type:_TYPE <type>\n
    422   # Name:_NAME <name>\n
    423   awk '
    424     BEGIN { RS = ""; }
    425     $0 !~ /_BEGIN_UNIONS\n(_UNION[^\n]*\n(_TYPE[^\n]*\n_NAME[^\n]*\n)*)*_END/ {
    426       print "_ERROR: Format check failed."; }
    427     { print $0; }
    428   '
    429 
    430 exit 0
    431