Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


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