OpenCores
URL https://opencores.org/ocsvn/zet86/zet86/trunk

Subversion Repositories zet86

[/] [zet86/] [trunk/] [soc/] [bios/] [biossums.c] - Blame information for rev 49

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 zeus
/*
2 43 zeus
 * $Id: biossums.c,v 1.7 2009-02-06 03:48:27 zeus Exp $
3 26 zeus
 *
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
 
19
/* biossums.c  --- written by Eike W. for the Bochs BIOS */
20
 
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <string.h>
24
 
25
typedef unsigned char byte;
26
 
27
void check( int value, char* message );
28
 
29
#define LEN_BIOS_DATA 0x10000
30
#define MAX_OFFSET    (LEN_BIOS_DATA - 1)
31
 
32
 
33
#define BIOS_OFFSET 0xFFFF
34
 
35
long chksum_bios_get_offset( byte* data, long offset );
36
byte chksum_bios_calc_value( byte* data, long offset );
37
byte chksum_bios_get_value(  byte* data, long offset );
38
void chksum_bios_set_value(  byte* data, long offset, byte value );
39
 
40
 
41
#define _32__LEN         9
42
#define _32__CHKSUM     10
43
 
44
#define _32__MINHDR     16
45
 
46
long chksum__32__get_offset( byte* data, long offset );
47
byte chksum__32__calc_value( byte* data, long offset );
48
byte chksum__32__get_value(  byte* data, long offset );
49
void chksum__32__set_value(  byte* data, long offset, byte value );
50
 
51
 
52
#define _MP__LEN         8
53
#define _MP__CHKSUM     10
54
 
55
#define _MP__MINHDR     16
56
 
57
long chksum__mp__get_offset( byte* data, long offset );
58
byte chksum__mp__calc_value( byte* data, long offset );
59
byte chksum__mp__get_value(  byte* data, long offset );
60
void chksum__mp__set_value(  byte* data, long offset, byte value );
61
 
62
 
63
#define PCMP_BASELEN     4
64
#define PCMP_CHKSUM      7
65
#define PCMP_EXT_LEN    40
66
#define PCMP_EXT_CHKSUM 42
67
 
68
#define PCMP_MINHDR     42
69
 
70
long chksum_pcmp_get_offset( byte* data, long offset );
71
byte chksum_pcmp_calc_value( byte* data, long offset );
72
byte chksum_pcmp_get_value(  byte* data, long offset );
73
void chksum_pcmp_set_value(  byte* data, long offset, byte value );
74
 
75
 
76
#define _PIR_LEN         6
77
#define _PIR_CHKSUM     31
78
 
79
#define _PIR_MINHDR     32
80
 
81
long chksum__pir_get_offset( byte *data, long offset );
82
byte chksum__pir_calc_value( byte* data, long offset );
83
byte chksum__pir_get_value(  byte* data, long offset );
84
void chksum__pir_set_value(  byte* data, long offset, byte value );
85
 
86
 
87
byte bios_data[LEN_BIOS_DATA];
88
long bios_len;
89
 
90
 
91
int main(int argc, char* argv[]) {
92
 
93
  FILE* stream;
94
  long  offset, tmp_offset;
95
  byte  cur_val = 0, new_val = 0;
96
  int   arg = 1, hits, pad = 0;
97
 
98
 
99
  if ((argc == 3) && (!strcmp(argv[1], "-pad"))) {
100
    pad = 1;
101
    arg = 2;
102
  } else if (argc != 2) {
103
    printf("Error. Need a file-name as an argument.\n");
104
    exit(EXIT_FAILURE);
105
  }
106
  memset(bios_data, 0xff, LEN_BIOS_DATA);
107
 
108
  if ((stream = fopen(argv[arg], "rb")) == NULL) {
109
    printf("Error opening %s for reading.\n", argv[arg]);
110
    exit(EXIT_FAILURE);
111
  }
112
  bios_len = fread(bios_data, 1, LEN_BIOS_DATA, stream);
113
  if ((bios_len < LEN_BIOS_DATA) && (pad == 0)) {
114
    printf("Error reading 64KBytes from %s.\n", argv[arg]);
115
    fclose(stream);
116
    exit(EXIT_FAILURE);
117
  }
118
  fclose(stream);
119
  if (pad == 1) goto write_bios;
120
 
121
  hits   = 0;
122
  offset = 0L;
123
  while( (tmp_offset = chksum__32__get_offset( bios_data, offset )) != -1L ) {
124
    offset  = tmp_offset;
125
    cur_val = chksum__32__get_value(  bios_data, offset );
126
    new_val = chksum__32__calc_value( bios_data, offset );
127
    printf( "\n\nPCI-Bios header at: 0x%4lX\n", offset  );
128
    printf( "Current checksum:     0x%02X\n",   cur_val );
129
    printf( "Calculated checksum:  0x%02X  ",   new_val );
130
    hits++;
131
  }
132
  if( hits == 1 && cur_val != new_val ) {
133
    printf( "Setting checksum." );
134
    chksum__32__set_value( bios_data, offset, new_val );
135
  }
136
  if( hits >= 2 ) {
137
    printf( "Multiple PCI headers! No checksum set." );
138
  }
139
  if( hits ) {
140
    printf( "\n" );
141
  }
142
 
143
 
144
  hits   = 0;
145
  offset = 0L;
146
  while( (tmp_offset = chksum__mp__get_offset( bios_data, offset )) != -1L ) {
147
    offset  = tmp_offset;
148
    cur_val = chksum__mp__get_value(  bios_data, offset );
149
    new_val = chksum__mp__calc_value( bios_data, offset );
150
    printf( "\n\nMP header at:       0x%4lX\n", offset  );
151
    printf( "Current checksum:     0x%02X\n",   cur_val );
152
    printf( "Calculated checksum:  0x%02X  ",   new_val );
153
    hits++;
154
  }
155
  if( hits == 1 && cur_val != new_val ) {
156
    printf( "Setting checksum." );
157
    chksum__mp__set_value( bios_data, offset, new_val );
158
  }
159
  if( hits >= 2 ) {
160
    printf( "Warning! Multiple MP headers. No checksum set." );
161
  }
162
  if( hits ) {
163
    printf( "\n" );
164
  }
165
 
166
 
167
  hits   = 0;
168
  offset = 0L;
169
  while( (tmp_offset = chksum_pcmp_get_offset( bios_data, offset )) != -1L ) {
170
    offset  = tmp_offset;
171
    cur_val = chksum_pcmp_get_value(  bios_data, offset );
172
    new_val = chksum_pcmp_calc_value( bios_data, offset );
173
    printf( "\n\nPCMP header at:     0x%4lX\n", offset  );
174
    printf( "Current checksum:     0x%02X\n",   cur_val );
175
    printf( "Calculated checksum:  0x%02X  ",   new_val );
176
    hits++;
177
  }
178
  if( hits == 1 && cur_val != new_val ) {
179
    printf( "Setting checksum." );
180
    chksum_pcmp_set_value( bios_data, offset, new_val );
181
  }
182
  if( hits >= 2 ) {
183
    printf( "Warning! Multiple PCMP headers. No checksum set." );
184
  }
185
  if( hits ) {
186
    printf( "\n" );
187
  }
188
 
189
 
190
  hits   = 0;
191
  offset = 0L;
192
  while( (tmp_offset = chksum__pir_get_offset( bios_data, offset )) != -1L ) {
193
    offset  = tmp_offset;
194
    cur_val = chksum__pir_get_value(  bios_data, offset );
195
    new_val = chksum__pir_calc_value( bios_data, offset );
196
    printf( "\n\n$PIR header at:     0x%4lX\n", offset  );
197
    printf( "Current checksum:     0x%02X\n",   cur_val );
198
    printf( "Calculated checksum:  0x%02X\n  ",  new_val );
199
    hits++;
200
  }
201
  if( hits == 1 && cur_val != new_val ) {
202
    printf( "Setting checksum." );
203
    chksum__pir_set_value( bios_data, offset, new_val );
204
  }
205
  if( hits >= 2 ) {
206
    printf( "Warning! Multiple $PIR headers. No checksum set." );
207
  }
208
  if( hits ) {
209
    printf( "\n" );
210
  }
211
 
212
 
213
  offset  = 0L;
214
  offset  = chksum_bios_get_offset( bios_data, offset );
215
  cur_val = chksum_bios_get_value(  bios_data, offset );
216
  new_val = chksum_bios_calc_value( bios_data, offset );
217
  printf( "\n\nBios checksum at:   0x%4lX\n", offset  );
218
  printf( "Current checksum:     0x%02X\n",   cur_val );
219
  printf( "Calculated checksum:  0x%02X  ",   new_val );
220
  if( cur_val != new_val ) {
221
    printf( "Setting checksum." );
222
    chksum_bios_set_value( bios_data, offset, new_val );
223
  }
224
  printf( "\n" );
225
 
226
write_bios:
227
  if ((stream = fopen(argv[arg], "wb")) == NULL) {
228
    printf("Error opening %s for writing.\n", argv[arg]);
229
    exit(EXIT_FAILURE);
230
  }
231
  if (fwrite(bios_data, 1, LEN_BIOS_DATA, stream) < LEN_BIOS_DATA) {
232
    printf("Error writing 64KBytes to %s.\n", argv[arg]);
233
    fclose(stream);
234
    exit(EXIT_FAILURE);
235
  }
236
  fclose(stream);
237
 
238
  return(EXIT_SUCCESS);
239
}
240
 
241
 
242
void check(int okay, char* message) {
243
 
244
  if (!okay) {
245
    printf("\n\nError. %s.\n", message);
246
    exit(EXIT_FAILURE);
247
  }
248
}
249
 
250
 
251
long chksum_bios_get_offset( byte* data, long offset ) {
252
 
253
  return( BIOS_OFFSET );
254
}
255
 
256
 
257
byte chksum_bios_calc_value( byte* data, long offset ) {
258
 
259
  int   i;
260
  byte  sum;
261
 
262
  sum = 0;
263
  for( i = 0; i < MAX_OFFSET; i++ ) {
264
    sum = sum + *( data + i );
265
  }
266
  sum = -sum;          /* iso ensures -s + s == 0 on unsigned types */
267
  return( sum );
268
}
269
 
270
 
271
byte chksum_bios_get_value( byte* data, long offset ) {
272
 
273
  return( *( data + BIOS_OFFSET ) );
274
}
275
 
276
 
277
void chksum_bios_set_value( byte* data, long offset, byte value ) {
278
 
279
  *( data + BIOS_OFFSET ) = value;
280
}
281
 
282
 
283
byte chksum__32__calc_value( byte* data, long offset ) {
284
 
285
  int           i;
286
  int           len;
287
  byte sum;
288
 
289
  check( offset + _32__MINHDR <= MAX_OFFSET, "_32_ header out of bounds" );
290
  len = *( data + offset + _32__LEN ) << 4;
291
  check( offset + len <= MAX_OFFSET, "_32_ header-length out of bounds" );
292
  sum = 0;
293
  for( i = 0; i < len; i++ ) {
294
    if( i != _32__CHKSUM ) {
295
      sum = sum + *( data + offset + i );
296
    }
297
  }
298
  sum = -sum;
299
  return( sum );
300
}
301
 
302
 
303
long chksum__32__get_offset( byte* data, long offset ) {
304
 
305
  long result = -1L;
306
 
307
  offset = offset + 0x0F;
308
  offset = offset & ~( 0x0F );
309
  while( offset + 16 < MAX_OFFSET ) {
310
    offset = offset + 16;
311
    if( *( data + offset + 0 ) == '_' && \
312
        *( data + offset + 1 ) == '3' && \
313
        *( data + offset + 2 ) == '2' && \
314
        *( data + offset + 3 ) == '_' ) {
315
      result = offset;
316
      break;
317
    }
318
  }
319
  return( result );
320
}
321
 
322
 
323
byte chksum__32__get_value( byte* data, long offset ) {
324
 
325
  check( offset + _32__CHKSUM <= MAX_OFFSET, "PCI-Bios checksum out of bounds" );
326
  return(  *( data + offset + _32__CHKSUM ) );
327
}
328
 
329
 
330
void chksum__32__set_value( byte* data, long offset, byte value ) {
331
 
332
  check( offset + _32__CHKSUM <= MAX_OFFSET, "PCI-Bios checksum out of bounds" );
333
  *( data + offset + _32__CHKSUM ) = value;
334
}
335
 
336
 
337
byte chksum__mp__calc_value( byte* data, long offset ) {
338
 
339
  int   i;
340
  int   len;
341
  byte  sum;
342
 
343
  check( offset + _MP__MINHDR <= MAX_OFFSET, "_MP_ header out of bounds" );
344
  len = *( data + offset + _MP__LEN ) << 4;
345
  check( offset + len <= MAX_OFFSET, "_MP_ header-length out of bounds" );
346
  sum = 0;
347
  for( i = 0; i < len; i++ ) {
348
    if( i != _MP__CHKSUM ) {
349
      sum = sum + *( data + offset + i );
350
    }
351
  }
352
  sum = -sum;
353
  return( sum );
354
}
355
 
356
 
357
long chksum__mp__get_offset( byte* data, long offset ) {
358
 
359
  long result = -1L;
360
 
361
  offset = offset + 0x0F;
362
  offset = offset & ~( 0x0F );
363
  while( offset + 16 < MAX_OFFSET ) {
364
    offset = offset + 16;
365
    if( *( data + offset + 0 ) == '_' && \
366
        *( data + offset + 1 ) == 'M' && \
367
        *( data + offset + 2 ) == 'P' && \
368
        *( data + offset + 3 ) == '_' ) {
369
      result = offset;
370
      break;
371
    }
372
  }
373
  return( result );
374
}
375
 
376
 
377
byte chksum__mp__get_value( byte* data, long offset ) {
378
 
379
  check( offset + _MP__CHKSUM <= MAX_OFFSET, "MP checksum out of bounds" );
380
  return( *( data + offset + _MP__CHKSUM ) );
381
}
382
 
383
 
384
void chksum__mp__set_value( byte* data, long offset, byte value ) {
385
 
386
  check( offset + _MP__CHKSUM <= MAX_OFFSET, "MP checksum out of bounds" );
387
  *( data + offset + _MP__CHKSUM ) = value;
388
}
389
 
390
 
391
byte chksum_pcmp_calc_value( byte* data, long offset ) {
392
 
393
  int   i;
394
  int   len;
395
  byte  sum;
396
 
397
  check( offset + PCMP_MINHDR <= MAX_OFFSET, "PCMP header out of bounds" );
398
  len  =   *( data + offset + PCMP_BASELEN )      + \
399
         ( *( data + offset + PCMP_BASELEN + 1 ) << 8 );
400
  check( offset + len <= MAX_OFFSET, "PCMP header-length out of bounds" );
401
  if( *( data + offset + PCMP_EXT_LEN )     | \
402
      *( data + offset + PCMP_EXT_LEN + 1 ) | \
403
      *( data + offset + PCMP_EXT_CHKSUM ) ) {
404
    check( 0, "PCMP header indicates extended tables (unsupported)" );
405
  }
406
  sum = 0;
407
  for( i = 0; i < len; i++ ) {
408
    if( i != PCMP_CHKSUM ) {
409
      sum = sum + *( data + offset + i );
410
    }
411
  }
412
  sum = -sum;
413
  return( sum );
414
}
415
 
416
 
417
long chksum_pcmp_get_offset( byte* data, long offset ) {
418
 
419
  long result = -1L;
420
 
421
  offset = offset + 0x0F;
422
  offset = offset & ~( 0x0F );
423
  while( offset + 16 < MAX_OFFSET ) {
424
    offset = offset + 16;
425
    if( *( data + offset + 0 ) == 'P' && \
426
        *( data + offset + 1 ) == 'C' && \
427
        *( data + offset + 2 ) == 'M' && \
428
        *( data + offset + 3 ) == 'P' ) {
429
      result = offset;
430
      break;
431
    }
432
  }
433
  return( result );
434
}
435
 
436
 
437
byte chksum_pcmp_get_value( byte* data, long offset ) {
438
 
439
  check( offset + PCMP_CHKSUM <= MAX_OFFSET, "PCMP checksum out of bounds" );
440
  return( *( data + offset + PCMP_CHKSUM ) );
441
}
442
 
443
 
444
void chksum_pcmp_set_value( byte* data, long offset, byte value ) {
445
 
446
  check( offset + PCMP_CHKSUM <= MAX_OFFSET, "PCMP checksum out of bounds" );
447
  *( data + offset + PCMP_CHKSUM ) = value;
448
}
449
 
450
 
451
byte chksum__pir_calc_value( byte* data, long offset ) {
452
 
453
  int   i;
454
  int   len;
455
  byte  sum;
456
 
457
  check( offset + _PIR_MINHDR <= MAX_OFFSET, "$PIR header out of bounds" );
458
  len  =   *( data + offset + _PIR_LEN )      + \
459
         ( *( data + offset + _PIR_LEN + 1 ) << 8 );
460
  check( offset + len <= MAX_OFFSET, "$PIR header-length out of bounds" );
461
  sum = 0;
462
  for( i = 0; i < len; i++ ) {
463
    if( i != _PIR_CHKSUM ) {
464
      sum = sum + *( data + offset + i );
465
    }
466
  }
467
  sum = -sum;
468
  return( sum );
469
}
470
 
471
 
472
long chksum__pir_get_offset( byte* data, long offset ) {
473
 
474
  long result = -1L;
475
 
476
  offset = offset + 0x0F;
477
  offset = offset & ~( 0x0F );
478
  while( offset + 16 < MAX_OFFSET ) {
479
    offset = offset + 16;
480
    if( *( data + offset + 0 ) == '$' && \
481
        *( data + offset + 1 ) == 'P' && \
482
        *( data + offset + 2 ) == 'I' && \
483
        *( data + offset + 3 ) == 'R' ) {
484
      result = offset;
485
      break;
486
    }
487
  }
488
  return( result );
489
}
490
 
491
 
492
byte chksum__pir_get_value( byte* data, long offset ) {
493
 
494
  check( offset + _PIR_CHKSUM <= MAX_OFFSET, "$PIR checksum out of bounds" );
495
  return(  *( data + offset + _PIR_CHKSUM ) );
496
}
497
 
498
 
499
void chksum__pir_set_value( byte* data, long offset, byte value ) {
500
 
501
  check( offset + _PIR_CHKSUM <= MAX_OFFSET, "$PIR checksum out of bounds" );
502
  *( data + offset + _PIR_CHKSUM ) = value;
503
}
504
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.