LTP GCOV extension - code coverage report
Current view: directory - fcode-utils/toke - emit.c
Test: FCode suite 1.0.2
Date: 2006-10-30 Instrumented lines: 149
Code covered: 100.0 % Executed lines: 149
Legend: not executed executed converted-only

       1                 : /*
       2                 :  *                     OpenBIOS - free your system! 
       3                 :  *                         ( FCode tokenizer )
       4                 :  *                          
       5                 :  *  emit.c - fcode emitter.
       6                 :  *  
       7                 :  *  This program is part of a free implementation of the IEEE 1275-1994 
       8                 :  *  Standard for Boot (Initialization Configuration) Firmware.
       9                 :  *
      10                 :  *  Copyright (C) 2001-2005 Stefan Reinauer, <stepan@openbios.org>
      11                 :  *
      12                 :  *  This program is free software; you can redistribute it and/or modify
      13                 :  *  it under the terms of the GNU General Public License as published by
      14                 :  *  the Free Software Foundation; version 2 of the License.
      15                 :  *
      16                 :  *  This program is distributed in the hope that it will be useful,
      17                 :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :  *  GNU General Public License for more details.
      20                 :  *
      21                 :  *  You should have received a copy of the GNU General Public License
      22                 :  *  along with this program; if not, write to the Free Software
      23                 :  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
      24                 :  *
      25                 :  */
      26                 : 
      27                 : /* **************************************************************************
      28                 :  *         Modifications made in 2005 by IBM Corporation
      29                 :  *      (C) Copyright 2005 IBM Corporation.  All Rights Reserved.
      30                 :  *      Modifications Author:  David L. Paktor    dlpaktor@us.ibm.com
      31                 :  **************************************************************************** */
      32                 : 
      33                 : /* **************************************************************************
      34                 :  *
      35                 :  *      Still to be done:
      36                 :  *          Re-arrange routine and variable locations to clarify the
      37                 :  *              functions of this file and its companion, stream.c 
      38                 :  *          This file should be concerned primarily with management
      39                 :  *              of the Outputs; stream.c should be primarily concerned
      40                 :  *              with management of the Inputs.
      41                 :  *          Hard to justify, pragmatically, but will make for easier
      42                 :  *              maintainability down the proverbial road...
      43                 :  *
      44                 :  **************************************************************************** */
      45                 : 
      46                 : #include <stdio.h>
      47                 : #include <stdlib.h>
      48                 : #include <string.h>
      49                 : #include <unistd.h>
      50                 : 
      51                 : #include "pcihdr.h"
      52                 : 
      53                 : #include "toke.h"
      54                 : #include "vocabfuncts.h"
      55                 : #include "stack.h"
      56                 : #include "scanner.h"
      57                 : #include "emit.h"
      58                 : #include "clflags.h"
      59                 : #include "errhandler.h"
      60                 : #include "stream.h"
      61                 : #include "nextfcode.h"
      62                 : 
      63                 : /* **************************************************************************
      64                 :  *
      65                 :  *          Global Variables Imported
      66                 :  *              verbose         Enable optional messages, set by "-v" switch
      67                 :  *              noerrors        "Ignore Errors" flag, set by "-i" switch
      68                 :  *
      69                 :  **************************************************************************** */
      70                 : 
      71                 : 
      72                 : /* **************************************************************************
      73                 :  *
      74                 :  *      Global Variables Exported:
      75                 :  *          opc                       Output Buffer Position Counter
      76                 :  *          pci_hdr_end_ob_off        Offsets into Output Buffer of end
      77                 :  *                                        of last PCI Header Block structure
      78                 :  *            (To help match up the offset printed in Tokenization_error()
      79                 :  *              with the offsets shown by the DeTokenizer)
      80                 :  *
      81                 :  **************************************************************************** */
      82                 : 
      83                 : unsigned int opc                = 0;
      84                 : unsigned int pci_hdr_end_ob_off = 0;   /*  0 means "Not initialized"  */
      85                 : 
      86                 : /* **************************************************************************
      87                 :  *
      88                 :  *      Macro to zero-fill a field of the size of the given structure
      89                 :  *          into the Output Buffer using the  emit_byte()  routine.
      90                 :  *
      91                 :  **************************************************************************** */
      92                 : 
      93                 : #define EMIT_STRUCT(x)  {int j; for (j=0; j < sizeof(x) ; j++ ) emit_byte(0); }
      94                 : 
      95                 : 
      96                 : /* **************************************************************************
      97                 :  *
      98                 :  *      Local Static Variables, offsets into Output Buffer of ...:
      99                 :  *          fcode_start_ob_off      First FCode-Start byte
     100                 :  *          fcode_hdr_ob_off        FCode Header (Format byte)
     101                 :  *          fcode_body_ob_off       First functional FCode after FCode Header.
     102                 :  *          pci_hdr_ob_off          Start of PCI ROM Header Block structure
     103                 :  *          pci_data_blk_ob_off     Start of PCI Data Header Block structure
     104                 :  *
     105                 :  *     For all of these, -1 means "Not initialized"
     106                 :  *
     107                 :  *************************************************************************** */
     108                 : 
     109                 : static  int fcode_start_ob_off = -1;
     110                 : static  int fcode_hdr_ob_off = -1;
     111                 : static  int fcode_body_ob_off = -1;
     112                 : static  int pci_hdr_ob_off = -1;
     113                 : static  int pci_data_blk_ob_off = -1;
     114                 : 
     115                 : /* **************************************************************************
     116                 :  *
     117                 :  *          These are to detect a particular error:  If FCode has
     118                 :  *              been written, before an Fcode-start<n> or before
     119                 :  *               a PCI-header
     120                 :  *
     121                 :  **************************************************************************** */
     122                 : 
     123                 : static bool fcode_written = FALSE;
     124                 : 
     125                 : /* **************************************************************************
     126                 :  *
     127                 :  *          Variables and Functions Imported, with
     128                 :  *          Exposure as Limited as possible:
     129                 :  *              ostart
     130                 :  *              olen
     131                 :  *              increase_output_buffer
     132                 :  *
     133                 :  **************************************************************************** */
     134                 : 
     135                 : extern u8 *ostart;
     136                 : extern int olen;
     137                 : extern void increase_output_buffer( void);
     138                 : 
     139                 : 
     140                 : /* **************************************************************************
     141                 :  *
     142                 :  *      Function name:  init_emit
     143                 :  *      Synopsis:       Initialize Output-related Local Static and Global
     144                 :  *                          Variables before starting Output.
     145                 :  *                      Exposure as Limited as possible.
     146                 :  *
     147                 :  **************************************************************************** */
     148                 : void init_emit( void);       /*    Prototype.  Limit Exposure.   */
     149                 : void init_emit( void)
     150             180 : {
     151             180 :     fcode_start_ob_off  = -1;
     152             180 :     fcode_hdr_ob_off    = -1;
     153             180 :     fcode_body_ob_off   = -1;
     154             180 :     pci_hdr_ob_off      = -1;
     155             180 :     pci_data_blk_ob_off = -1;
     156             180 :     opc                 =  0;
     157             180 :     pci_hdr_end_ob_off  =  0;
     158             180 :     fcode_written       = FALSE;
     159             180 :     haveend             = FALSE;   /*  Get this one too...  */
     160             180 : }
     161                 : 
     162                 : 
     163                 : /* **************************************************************************
     164                 :  *
     165                 :  *      Function name:  emit_byte
     166                 :  *      Synopsis:       Fundamental routine for placing a byte
     167                 :  *                          into the Output Buffer.  Also, check
     168                 :  *                          whether the buffer needs to be expanded.
     169                 :  *                      For internal use only.
     170                 :  *
     171                 :  **************************************************************************** */
     172                 : 
     173                 : static void emit_byte(u8 data)
     174         1992840 : {
     175         1992840 :         if ( opc == olen)
     176                 :         {
     177               6 :             increase_output_buffer();
     178                 :         }
     179                 :         
     180                 : 
     181         1992840 :         *(ostart+opc) = data ;
     182         1992840 :         opc++;
     183         1992840 : }
     184                 : 
     185                 : void emit_fcode(u16 tok)
     186          174379 : {
     187          174379 :         if ((tok>>8))
     188           15526 :                 emit_byte(tok>>8);
     189                 : 
     190          174379 :         emit_byte(tok&0xff);
     191          174379 :         fcode_written = TRUE;
     192          174379 : }
     193                 : 
     194                 : static void emit_num32(u32 num)
     195           13570 : {
     196           13570 :         emit_byte(num>>24);
     197           13570 :         emit_byte((num>>16)&0xff);
     198           13570 :         emit_byte((num>>8)&0xff);
     199           13570 :         emit_byte(num&0xff);
     200                 : 
     201           13570 : }
     202                 : 
     203                 : /* **************************************************************************
     204                 :  *
     205                 :  *      Function name:  user_emit_byte
     206                 :  *      Synopsis:       Action of user-mandated call to emit-byte.
     207                 :  *                          Covers the corner-case where this is the
     208                 :  *                          first command issued in the source input.
     209                 :  *
     210                 :  **************************************************************************** */
     211                 : 
     212                 : void user_emit_byte(u8 data)
     213             112 : {
     214             112 :         emit_byte( data);
     215             112 :         fcode_written = TRUE;
     216             112 : }
     217                 : 
     218                 : void emit_offset(s16 offs)
     219            6255 : {
     220                 :     /*  Calling routine will test for out-of-range FCode-Offset  */
     221            6255 :         if (offs16)
     222            6112 :                 emit_byte(offs>>8);
     223            6255 :         emit_byte(offs&0xff);
     224            6255 : }
     225                 : 
     226                 : void emit_literal(u32 num)
     227           13570 : {
     228           13570 :     emit_token("b(lit)");
     229           13570 :     emit_num32(num);
     230           13570 : }
     231                 : 
     232                 : void emit_string(u8 *string, signed int cnt)
     233           49843 : {
     234           49843 :         signed int i=0;
     235           49843 :         signed int cnt_cpy = cnt;
     236                 :         
     237           49843 :         if ( cnt_cpy > STRING_LEN_MAX )
     238                 :         {
     239               1 :             tokenization_error( TKERROR,
     240                 :                 "String too long:  %d characters.  Truncating.\n",cnt);
     241               1 :             cnt_cpy = STRING_LEN_MAX ;
     242                 :         }
     243           49843 :         emit_byte(cnt_cpy);
     244         1721644 :         for (i=0; i<cnt_cpy; i++)
     245         1671801 :                 emit_byte(string[i]);
     246           49843 : }
     247                 : 
     248                 : void emit_fcodehdr(const char *starter_name)
     249             191 : {
     250                 :         
     251                 :    /*  Check for error conditions   */
     252             191 :     if ( fcode_written )
     253                 :     {
     254               5 :         tokenization_error( TKERROR ,
     255                 :             "Cannot create FCode header after FCode output has begun.\n");
     256               5 :         if ( ! noerrors ) return ;
     257                 :     }
     258                 : 
     259                 :         fcode_header_t *fcode_hdr;
     260                 : 
     261             189 :         fcode_start_ob_off = opc;
     262             189 :         emit_token( starter_name );
     263                 : 
     264             189 :         fcode_hdr_ob_off = opc;
     265             189 :         fcode_hdr = (fcode_header_t *)(ostart+fcode_hdr_ob_off);
     266                 : 
     267             189 :         EMIT_STRUCT(fcode_header_t);
     268                 : 
     269             189 :         fcode_body_ob_off = opc;
     270                 : 
     271                 :         /* Format = 8 means we comply with IEEE 1275-1994 */
     272             189 :         fcode_hdr->format = 0x08;
     273                 : 
     274                 : }
     275                 : 
     276                 : /* **************************************************************************
     277                 :  *
     278                 :  *      Function name:    finish_fcodehdr
     279                 :  *          Fill in the FCode header's checksum and length fields, and
     280                 :  *              reset the FCode-header pointer for the next image.
     281                 :  *
     282                 :  *          If  haveend  is true then the end0 has already been written
     283                 :  *              and  fcode_ender()  has been called.
     284                 :  *
     285                 :  *          Print a WARNING message if the end-of-file was encountered
     286                 :  *              without an end0 or an fcode-end
     287                 :  *
     288                 :  *          Print an informative message to standard-output giving the
     289                 :  *              checksum.  Call  list_fcode_ranges()  to print the
     290                 :  *              value of the last FCode-token that was assigned or
     291                 :  *              the Ranges of assigned FCode-token values if so be...
     292                 :  *              The final FCode-binary file-length will be printed
     293                 :  *              when the binary file is being closed.
     294                 :  *
     295                 :  **************************************************************************** */
     296                 : 
     297                 : void finish_fcodehdr(void)
     298             196 : {
     299                 : 
     300             196 :         if( fcode_hdr_ob_off == -1 )
     301                 :         {
     302               3 :                 tokenization_error( TKERROR,
     303                 :                     "Missing FCode header.\n");
     304               3 :                 return ;
     305                 :         }
     306                 : 
     307                 :         /* If the program did not end cleanly, we'll handle it */
     308             193 :         if (!haveend)
     309                 :         {
     310               6 :             tokenization_error ( WARNING,
     311                 :             "End-of-file encountered without END0 or FCODE-END.  "
     312                 :                 "Supplying END0\n");
     313               6 :                 emit_token("end0");
     314               6 :             fcode_ender();
     315                 :         }
     316                 : 
     317                 :         /*  Calculate and place checksum and length, if haven't already  */
     318             193 :         if ( fcode_start_ob_off != -1 )
     319                 :         {
     320                 :             u16 checksum;
     321                 :             int length;
     322                 : 
     323             187 :             u8 *fcode_body = ostart+fcode_body_ob_off;
     324             187 :             u8 *ob_end = ostart+opc;
     325                 :             fcode_header_t *fcode_hdr =
     326             187 :                  (fcode_header_t *)(ostart+fcode_hdr_ob_off);
     327                 :         
     328             187 :             length = opc - fcode_start_ob_off;
     329                 : 
     330             187 :             for ( checksum = 0;
     331         1960753 :                       fcode_body < ob_end ;
     332         1960379 :                           checksum += *(fcode_body++) ) ;
     333                 : 
     334             187 :             BIG_ENDIAN_WORD_STORE(fcode_hdr->checksum , checksum);
     335             187 :             BIG_ENDIAN_LONG_STORE(fcode_hdr->length , length);
     336                 : 
     337             187 :         if (verbose)
     338                 :             {
     339             185 :                 printf( "toke: checksum is 0x%04x (%d bytes).  ",
     340                 :                     checksum, length);
     341             185 :                 list_fcode_ranges( TRUE);
     342                 :             }
     343                 :         }
     344                 : 
     345                 :         /*  Reset things for the next image...   */
     346             193 :         fcode_start_ob_off = -1;
     347             193 :         fcode_hdr_ob_off   = -1;
     348             193 :         fcode_body_ob_off  = -1;
     349             193 :         fcode_written      = FALSE;
     350             193 :         haveend=FALSE;
     351                 : }
     352                 : 
     353                 : /* **************************************************************************
     354                 :  *
     355                 :  *      Function name:  emit_pci_rom_hdr
     356                 :  *      Synopsis:       Write the PCI ROM Header Block into the Output Buffer
     357                 :  *
     358                 :  *      Inputs:
     359                 :  *         Parameters:                   NONE
     360                 :  *         Global Variables:        
     361                 :  *             opc                       Output Buffer Position Counter
     362                 :  *             ostart                    Start of Output Buffer
     363                 :  *
     364                 :  *      Outputs:
     365                 :  *         Returned Value:               NONE
     366                 :  *         Global Variables:    
     367                 :  *             pci_hdr_ob_off            PCI ROM Header Block Position
     368                 :  *                                           (Offset) in Output Buffer
     369                 :  *         FCode Output buffer:
     370                 :  *             Write the part of the PCI ROM Header Block we know:
     371                 :  *                 Fill in the signature and the field reserved for
     372                 :  *                 "processor architecture unique data".
     373                 :  *             Fill in the "Pointer to PCI Data Structure" with the
     374                 :  *                 size of the data structure, because the first PCI
     375                 :  *                 Data Structure will follow immediately.
     376                 :  *
     377                 :  *      Error Detection:   (Handled by calling routine)
     378                 :  *
     379                 :  **************************************************************************** */
     380                 : 
     381                 : static void emit_pci_rom_hdr(void)
     382              32 : {
     383                 :     rom_header_t *pci_hdr;
     384              32 :     pci_hdr_ob_off = opc;
     385              32 :     pci_hdr = (rom_header_t *)(ostart + pci_hdr_ob_off);
     386                 : 
     387              32 :     EMIT_STRUCT(rom_header_t);
     388                 :         
     389                 :         /* PCI start signature */
     390              32 :     LITTLE_ENDIAN_WORD_STORE(pci_hdr->signature,0xaa55);
     391                 :         
     392                 :         /* Processor architecture */
     393                 :         /*  Note:
     394                 :          *  The legacy code used to read:
     395                 :          *
     396                 :          *        pci_hdr->reserved[0] = 0x34;
     397                 :          *
     398                 :          *  I don't know what significance the literal  34  had, but
     399                 :          *      by what might just be an odd coincidence, it is equal
     400                 :          *      to the combined lengths of the  PCI-ROM-  and  PCI-Data-
     401                 :          *      headers.
     402                 :          *
     403                 :          *  I suspect that it is more than merely an odd coincidence,
     404                 :          *      and that the following would be preferable:
     405                 :          */
     406                 : 
     407              32 :     LITTLE_ENDIAN_WORD_STORE( pci_hdr->reserved ,
     408                 :         (sizeof(rom_header_t) + sizeof(pci_data_t)) ) ;
     409                 : 
     410                 :         /* already handled padding */
     411                 : 
     412                 :         /* pointer to start of PCI data structure */
     413              32 :     LITTLE_ENDIAN_WORD_STORE(pci_hdr->data_ptr, sizeof(rom_header_t) );
     414                 : 
     415              32 : }
     416                 :         
     417                 : /* **************************************************************************
     418                 :  *
     419                 :  *      Function name:  emit_pci_data_block
     420                 :  *      Synopsis:       Write the PCI Data Block into the Output Buffer
     421                 :  *
     422                 :  *      Inputs:
     423                 :  *         Parameters:                   NONE
     424                 :  *         Global Variables:        
     425                 :  *             opc                       Output Buffer Position Counter
     426                 :  *         Data-Stack Items:
     427                 :  *             Top:                      Class Code
     428                 :  *             Next:                     Device ID
     429                 :  *             3rd:                      Vendor ID
     430                 :  *
     431                 :  *      Outputs:
     432                 :  *         Returned Value:               NONE
     433                 :  *         Global Variables:    
     434                 :  *             pci_data_blk_ob_off       PCI Data Header Block Position
     435                 :  *                                           (Offset) in Output Buffer
     436                 :  *         Data-Stack, # of Items Popped:  3
     437                 :  *         FCode Output buffer:
     438                 :  *             Write the PCI Data Header Block:  Fill in the signature,
     439                 :  *                 Vendor ID, Device ID and Class Code, and everything
     440                 :  *                 else whose value we know.  (Size and Checksum will
     441                 :  *                 have to wait until we finish the image...)
     442                 :  *         Printout:
     443                 :  *             Advisory of Vendor, Device and Class 
     444                 :  *
     445                 :  *      Error Detection:   (Handled by calling routine)
     446                 :  *
     447                 :  **************************************************************************** */
     448                 : 
     449                 : static void emit_pci_data_block(void)
     450              32 : {
     451                 :     pci_data_t *pci_data_blk;
     452              32 :     u32 class_id = dpop();
     453              32 :     u16 dev_id   = dpop();
     454              32 :     u16 vend_id  = dpop();
     455                 : 
     456              32 :     pci_data_blk_ob_off = opc;
     457              32 :     pci_data_blk = (pci_data_t *)(ostart + pci_data_blk_ob_off);
     458                 : 
     459              32 :     EMIT_STRUCT(pci_data_t);
     460                 : 
     461              32 :     BIG_ENDIAN_LONG_STORE(pci_data_blk->signature , PCI_DATA_HDR );
     462                 : 
     463              32 :     LITTLE_ENDIAN_WORD_STORE(pci_data_blk->vendor , vend_id );
     464              32 :     LITTLE_ENDIAN_WORD_STORE(pci_data_blk->device , dev_id );
     465              32 :     LITTLE_ENDIAN_TRIPLET_STORE(pci_data_blk->class_code , class_id );
     466                 : 
     467              32 :     LITTLE_ENDIAN_WORD_STORE(pci_data_blk->dlen ,  sizeof(pci_data_t) );
     468                 : 
     469              32 :     pci_data_blk->drevision = PCI_DATA_STRUCT_REV ;
     470                 : 
     471                 :         /* code type = open firmware = 1 */
     472              32 :     pci_data_blk->code_type = 1;
     473                 : 
     474                 :         /* last image flag */
     475              32 :     pci_data_blk->last_image_flag = pci_is_last_image ? 0x80 : 0 ;
     476                 : 
     477              32 :     tokenization_error(INFO ,
     478                 :         "PCI header vendor id=0x%04x, "
     479                 :             "device id=0x%04x, class=%06x\n",
     480                 :                 vend_id, dev_id, class_id );
     481                 : 
     482              32 : }
     483                 : 
     484                 : /* **************************************************************************
     485                 :  *
     486                 :  *      Function name:  emit_pcihdr
     487                 :  *      Synopsis:       Supervise the writing of PCI Header information
     488                 :  *                          into the Output Buffer, when the  PCI-HEADER
     489                 :  *                          tokenizer directive has been encountered.
     490                 :  *
     491                 :  *      Inputs:
     492                 :  *         Parameters:                   NONE
     493                 :  *         Global Variables:        
     494                 :  *             opc                       Output Buffer Position Counter      
     495                 :  *             fcode_start_ob_off        Initted if FCode output has begun
     496                 :  *             noerrors                  The "Ignore Errors" flag
     497                 :  *
     498                 :  *      Outputs:
     499                 :  *         Returned Value:               NONE
     500                 :  *         Global Variables:    
     501                 :  *            pci_hdr_end_ob_off         Set to the Output Buffer Position
     502                 :  *                                           Counter after the PCI Header
     503                 :  *         FCode Output buffer      
     504                 :  *            :The beginning of the PCI Header will be entered, waiting for
     505                 :  *                 the fields that could not be determined until the end
     506                 :  *                 to be filled in.
     507                 :  *
     508                 :  *      Error Detection:
     509                 :  *          An attempt to write a PCI Header after FCode output -- either an
     510                 :  *              Fcode-start<n> or ordinary FCode -- has begun is an ERROR.
     511                 :  *              Report it; do nothing further, unless "Ignore Errors" is set.
     512                 :  *
     513                 :  **************************************************************************** */
     514                 : 
     515                 : void emit_pcihdr(void)
     516              32 : {
     517                 : 
     518                 :     /*  Check for error conditions   */
     519              32 :     if (
     520                 :     /*  FCODE-START<n>  has already been issued  */
     521                 :               ( fcode_start_ob_off != -1 )
     522                 :     /*  Other FCode has been written             */
     523                 :               ||  fcode_written
     524                 :          )
     525                 :     {
     526               1 :         tokenization_error( TKERROR ,
     527                 :             "Cannot create PCI header after FCode output has begun.\n");
     528               1 :         if ( ! noerrors ) return ;
     529                 :         }
     530                 : 
     531              32 :         emit_pci_rom_hdr();
     532                 : 
     533              32 :         emit_pci_data_block();
     534                 : 
     535              32 :         pci_hdr_end_ob_off = opc;
     536                 : }
     537                 : 
     538                 : /* **************************************************************************
     539                 :  *
     540                 :  *      Function name:  finish_pcihdr
     541                 :  *      Synopsis:       Fill-in the fields of the PCI Header that could
     542                 :  *                      not be determined until the end of the PCI-block.
     543                 :  *
     544                 :  *************************************************************************** */
     545                 : 
     546                 : void finish_pcihdr(void)
     547              33 : {
     548                 : 
     549                 :         u32 imagesize ;
     550                 :         u32 imageblocks;
     551                 :         int padding;
     552                 :         
     553                 :         rom_header_t *pci_hdr;
     554                 :         pci_data_t   *pci_data_blk;
     555                 : 
     556              33 :         if( pci_data_blk_ob_off == -1 )
     557                 :         {
     558               1 :             tokenization_error( TKERROR,
     559                 :                 "%s without PCI-HEADER\n", strupr(statbuf) );
     560               1 :             return ;
     561                 :         }
     562                 : 
     563              32 :         pci_hdr = (rom_header_t *)(ostart + pci_hdr_ob_off);
     564              32 :         pci_data_blk = (pci_data_t *)(ostart + pci_data_blk_ob_off);
     565                 : 
     566                 :         /* fix up vpd */
     567              32 :         LITTLE_ENDIAN_WORD_STORE(pci_data_blk->vpd, pci_vpd);
     568                 : 
     569                 :         /*   Calculate image size and padding */
     570              32 :         imagesize = opc - pci_hdr_ob_off;     /*  Padding includes PCI hdr  */
     571              32 :         imageblocks = (imagesize + 511) >> 9; /*  Size in 512-byte blocks   */
     572              32 :         padding = (imageblocks << 9) - imagesize;
     573                 : 
     574                 :         /* fix up image size. */
     575              32 :         LITTLE_ENDIAN_WORD_STORE(pci_data_blk->ilen, imageblocks);
     576                 :         
     577                 :         /* fix up revision */
     578              32 :         if ( big_end_pci_image_rev )
     579                 :         {
     580               2 :             BIG_ENDIAN_WORD_STORE(pci_data_blk->irevision, pci_image_rev);
     581                 :         }else{
     582              30 :             LITTLE_ENDIAN_WORD_STORE(pci_data_blk->irevision, pci_image_rev);
     583                 :         }
     584                 :         
     585                 :         /* fix up last image flag */
     586              32 :         pci_data_blk->last_image_flag = pci_is_last_image ? 0x80 : 0 ;
     587                 :         
     588                 :         /* align to 512bytes */
     589                 :         
     590              32 :         printf("Adding %d bytes of zero padding to PCI image.\n",padding);
     591           11609 :         while (padding--)
     592           11545 :                 emit_byte(0);
     593              32 :         if ( ! pci_is_last_image )
     594                 :         {
     595              13 :             printf("Note:  PCI header is not last image.\n");
     596                 :         }
     597              32 :         printf("\n");
     598                 :         
     599              32 :         pci_hdr_ob_off      = -1;
     600              32 :         pci_data_blk_ob_off = -1;
     601              32 :         pci_hdr_end_ob_off  =  0;
     602                 : }
     603                 : 
     604                 : 
     605                 : /* **************************************************************************
     606                 :  *
     607                 :  *      Function name:  finish_headers
     608                 :  *      Synopsis:       Fill-in the fields of the FCode- and PCI- Headers
     609                 :  *                      that could not be determined until the end.
     610                 :  *
     611                 :  *************************************************************************** */
     612                 : 
     613                 : void finish_headers(void)
     614             178 : {
     615             178 :         if (fcode_hdr_ob_off != -1) finish_fcodehdr();
     616             178 :         if (pci_hdr_ob_off != -1) finish_pcihdr();
     617             178 : }
     618                 : 

Generated by: LTP GCOV extension version 1.5