Annotation of qemu/roms/vgabios/biossums.c, revision 1.1.1.1

1.1       root        1: /* biossums.c  --- written by Eike W. for the Bochs BIOS */
                      2: /* adapted for the LGPL'd VGABIOS by vruppert */
                      3: 
                      4: /*  This library is free software; you can redistribute it and/or
                      5:  *  modify it under the terms of the GNU Lesser General Public
                      6:  *  License as published by the Free Software Foundation; either
                      7:  *  version 2 of the License, or (at your option) any later version.
                      8:  *
                      9:  *  This library is distributed in the hope that it will be useful,
                     10:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     12:  *  Lesser General Public License for more details.
                     13:  *
                     14:  *  You should have received a copy of the GNU Lesser General Public
                     15:  *  License along with this library; if not, write to the Free Software
                     16:  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
                     17:  */
                     18: #include <stdlib.h>
                     19: #include <stdio.h>
                     20: #include <string.h>
                     21: 
                     22: typedef unsigned char byte;
                     23: 
                     24: void check( int value, char* message );
                     25: 
                     26: #define MAX_BIOS_DATA 0x10000
                     27: 
                     28: long chksum_bios_get_offset( byte* data, long offset );
                     29: byte chksum_bios_calc_value( byte* data, long offset );
                     30: byte chksum_bios_get_value(  byte* data, long offset );
                     31: void chksum_bios_set_value(  byte* data, long offset, byte value );
                     32: 
                     33: #define PMID_LEN        20
                     34: #define PMID_CHKSUM     19
                     35: 
                     36: long chksum_pmid_get_offset( byte* data, long offset );
                     37: byte chksum_pmid_calc_value( byte* data, long offset );
                     38: byte chksum_pmid_get_value(  byte* data, long offset );
                     39: void chksum_pmid_set_value(  byte* data, long offset, byte value );
                     40: 
                     41: #define PCIR_LEN        24
                     42: 
                     43: long chksum_pcir_get_offset( byte* data, long offset );
                     44: 
                     45: 
                     46: byte bios_data[MAX_BIOS_DATA];
                     47: long bios_len;
                     48: 
                     49: 
                     50: int main(int argc, char* argv[])
                     51: {
                     52:   FILE* stream;
                     53:   long  offset, tmp_offset, pcir_offset;
                     54:   byte  bios_len_byte, cur_val = 0, new_val = 0;
                     55:   int   hits, modified;
                     56: 
                     57:   if (argc != 2) {
                     58:     printf( "Error. Need a file-name as an argument.\n" );
                     59:     exit( EXIT_FAILURE );
                     60:   }
                     61: 
                     62:   if ((stream = fopen(argv[1], "rb")) == NULL) {
                     63:     printf("Error opening %s for reading.\n", argv[1]);
                     64:     exit(EXIT_FAILURE);
                     65:   }
                     66:   memset(bios_data, 0, MAX_BIOS_DATA);
                     67:   bios_len = fread(bios_data, 1, MAX_BIOS_DATA, stream);
                     68:   if (bios_len > MAX_BIOS_DATA) {
                     69:     printf("Error reading max. 65536 Bytes from %s.\n", argv[1]);
                     70:     fclose(stream);
                     71:     exit(EXIT_FAILURE);
                     72:   }
                     73:   fclose(stream);
                     74:   modified = 0;
                     75:   if (bios_len < 0x8000) {
                     76:     bios_len = 0x8000;
                     77:     modified = 1;
                     78:   } else if ((bios_len & 0x1FF) != 0) {
                     79:     bios_len = (bios_len + 0x200) & ~0x1FF;
                     80:     modified = 1;
                     81:   }
                     82:   bios_len_byte = (byte)(bios_len / 512);
                     83:   if (bios_len_byte != bios_data[2]) {
                     84:     if (modified == 0) {
                     85:       bios_len += 0x200;
                     86:     }
                     87:     bios_data[2] = (byte)(bios_len / 512);
                     88:     modified = 1;
                     89:   }
                     90: 
                     91:   hits   = 0;
                     92:   offset = 0L;
                     93:   while( (tmp_offset = chksum_pmid_get_offset( bios_data, offset )) != -1L ) {
                     94:     offset  = tmp_offset;
                     95:     cur_val = chksum_pmid_get_value(  bios_data, offset );
                     96:     new_val = chksum_pmid_calc_value( bios_data, offset );
                     97:     printf( "\nPMID entry at: 0x%4lX\n", offset  );
                     98:     printf( "Current checksum:     0x%02X\n",   cur_val );
                     99:     printf( "Calculated checksum:  0x%02X  ",   new_val );
                    100:     hits++;
                    101:   }
                    102:   if ((hits == 1) && (cur_val != new_val)) {
                    103:     printf("Setting checksum.");
                    104:     chksum_pmid_set_value( bios_data, offset, new_val );
                    105:     if (modified == 0) {
                    106:       bios_len += 0x200;
                    107:       bios_data[2]++;
                    108:     }
                    109:     modified = 1;
                    110:   }
                    111:   if (hits >= 2) {
                    112:     printf( "Multiple PMID entries! No checksum set." );
                    113:   }
                    114:   if (hits) {
                    115:     printf("\n");
                    116:   }
                    117: 
                    118:   offset = 0L;
                    119:   pcir_offset = chksum_pcir_get_offset( bios_data, offset );
                    120:   if (pcir_offset != -1L) {
                    121:     if (bios_data[pcir_offset + 16] != bios_data[2]) {
                    122:       bios_data[pcir_offset + 16] = bios_data[2];
                    123:       if (modified == 0) {
                    124:         bios_len += 0x200;
                    125:         bios_data[2]++;
                    126:         bios_data[pcir_offset + 16]++;
                    127:       }
                    128:       modified = 1;
                    129:     }
                    130:   }
                    131: 
                    132:   offset  = 0L;
                    133:   do {
                    134:     offset  = chksum_bios_get_offset(bios_data, offset);
                    135:     cur_val = chksum_bios_get_value(bios_data, offset);
                    136:     new_val = chksum_bios_calc_value(bios_data, offset);
                    137:     if ((cur_val != new_val) && (modified == 0)) {
                    138:       bios_len += 0x200;
                    139:       bios_data[2]++;
                    140:       if (pcir_offset != -1L) {
                    141:         bios_data[pcir_offset + 16]++;
                    142:       }
                    143:       modified = 1;
                    144:     } else {
                    145:       printf("\nBios checksum at:   0x%4lX\n", offset);
                    146:       printf("Current checksum:     0x%02X\n", cur_val);
                    147:       printf("Calculated checksum:  0x%02X  ", new_val);
                    148:       if (cur_val != new_val) {
                    149:         printf("Setting checksum.");
                    150:         chksum_bios_set_value(bios_data, offset, new_val);
                    151:         cur_val = new_val;
                    152:         modified = 1;
                    153:       }
                    154:       printf( "\n" );
                    155:     }
                    156:   } while (cur_val != new_val);
                    157: 
                    158:   if (modified == 1) {
                    159:     if ((stream = fopen( argv[1], "wb")) == NULL) {
                    160:       printf("Error opening %s for writing.\n", argv[1]);
                    161:       exit(EXIT_FAILURE);
                    162:     }
                    163:     if (fwrite(bios_data, 1, bios_len, stream) < bios_len) {
                    164:       printf("Error writing %d KBytes to %s.\n", bios_len / 1024, argv[1]);
                    165:       fclose(stream);
                    166:       exit(EXIT_FAILURE);
                    167:     }
                    168:     fclose(stream);
                    169:   }
                    170: 
                    171:   return (EXIT_SUCCESS);
                    172: }
                    173: 
                    174: 
                    175: void check( int okay, char* message ) {
                    176: 
                    177:   if( !okay ) {
                    178:     printf( "\n\nError. %s.\n", message );
                    179:     exit( EXIT_FAILURE );
                    180:   }
                    181: }
                    182: 
                    183: 
                    184: long chksum_bios_get_offset( byte* data, long offset ) {
                    185: 
                    186:   return (bios_len - 1);
                    187: }
                    188: 
                    189: 
                    190: byte chksum_bios_calc_value( byte* data, long offset ) {
                    191: 
                    192:   int   i;
                    193:   byte  sum;
                    194: 
                    195:   sum = 0;
                    196:   for( i = 0; i < offset; i++ ) {
                    197:     sum = sum + *( data + i );
                    198:   }
                    199:   sum = -sum;          /* iso ensures -s + s == 0 on unsigned types */
                    200:   return( sum );
                    201: }
                    202: 
                    203: 
                    204: byte chksum_bios_get_value( byte* data, long offset ) {
                    205: 
                    206:   return( *( data + offset ) );
                    207: }
                    208: 
                    209: 
                    210: void chksum_bios_set_value( byte* data, long offset, byte value ) {
                    211: 
                    212:   *( data + offset ) = value;
                    213: }
                    214: 
                    215: 
                    216: byte chksum_pmid_calc_value( byte* data, long offset ) {
                    217: 
                    218:   int           i;
                    219:   int           len;
                    220:   byte sum;
                    221: 
                    222:   len = PMID_LEN;
                    223:   check((offset + len) <= (bios_len - 1), "PMID entry length out of bounds" );
                    224:   sum = 0;
                    225:   for( i = 0; i < len; i++ ) {
                    226:     if( i != PMID_CHKSUM ) {
                    227:       sum = sum + *( data + offset + i );
                    228:     }
                    229:   }
                    230:   sum = -sum;
                    231:   return( sum );
                    232: }
                    233: 
                    234: 
                    235: long chksum_pmid_get_offset( byte* data, long offset ) {
                    236: 
                    237:   long result = -1L;
                    238: 
                    239:   while ((offset + PMID_LEN) < (bios_len - 1)) {
                    240:     offset = offset + 1;
                    241:     if( *( data + offset + 0 ) == 'P' && \
                    242:         *( data + offset + 1 ) == 'M' && \
                    243:         *( data + offset + 2 ) == 'I' && \
                    244:         *( data + offset + 3 ) == 'D' ) {
                    245:       result = offset;
                    246:       break;
                    247:     }
                    248:   }
                    249:   return( result );
                    250: }
                    251: 
                    252: 
                    253: byte chksum_pmid_get_value( byte* data, long offset ) {
                    254: 
                    255:   check((offset + PMID_CHKSUM) <= (bios_len - 1), "PMID checksum out of bounds" );
                    256:   return(  *( data + offset + PMID_CHKSUM ) );
                    257: }
                    258: 
                    259: 
                    260: void chksum_pmid_set_value( byte* data, long offset, byte value ) {
                    261: 
                    262:   check((offset + PMID_CHKSUM) <= (bios_len - 1), "PMID checksum out of bounds" );
                    263:   *( data + offset + PMID_CHKSUM ) = value;
                    264: }
                    265: 
                    266: 
                    267: long chksum_pcir_get_offset( byte* data, long offset ) {
                    268: 
                    269:   long result = -1L;
                    270: 
                    271:   while ((offset + PCIR_LEN) < (bios_len - 1)) {
                    272:     offset = offset + 1;
                    273:     if( *( data + offset + 0 ) == 'P' && \
                    274:         *( data + offset + 1 ) == 'C' && \
                    275:         *( data + offset + 2 ) == 'I' && \
                    276:         *( data + offset + 3 ) == 'R' ) {
                    277:       result = offset;
                    278:       break;
                    279:     }
                    280:   }
                    281:   return( result );
                    282: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.