X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=blobdiff_plain;f=bios%2Frombios%2Fbiossums.c;fp=bios%2Frombios%2Fbiossums.c;h=be12e49f3598186ef89a09647de4973acc57f36f;hp=0000000000000000000000000000000000000000;hb=d34450b1e6fe3c2e1295c268c1722c669ba8d545;hpb=1a24d4e8fb3918a42b124777db5b41940150023e diff --git a/bios/rombios/biossums.c b/bios/rombios/biossums.c new file mode 100644 index 0000000..be12e49 --- /dev/null +++ b/bios/rombios/biossums.c @@ -0,0 +1,478 @@ +/* biossums.c --- written by Eike W. */ + +#include +#include + +typedef unsigned char byte; + +void check( int value, char* message ); + +#define LEN_BIOS_DATA 0x10000 +#define MAX_OFFSET (LEN_BIOS_DATA - 1) + + +#define BIOS_OFFSET 0xFFFF + +long chksum_bios_get_offset( byte* data, long offset ); +byte chksum_bios_calc_value( byte* data, long offset ); +byte chksum_bios_get_value( byte* data, long offset ); +void chksum_bios_set_value( byte* data, long offset, byte value ); + + +#define _32__LEN 9 +#define _32__CHKSUM 10 + +#define _32__MINHDR 16 + +long chksum__32__get_offset( byte* data, long offset ); +byte chksum__32__calc_value( byte* data, long offset ); +byte chksum__32__get_value( byte* data, long offset ); +void chksum__32__set_value( byte* data, long offset, byte value ); + + +#define _MP__LEN 8 +#define _MP__CHKSUM 10 + +#define _MP__MINHDR 16 + +long chksum__mp__get_offset( byte* data, long offset ); +byte chksum__mp__calc_value( byte* data, long offset ); +byte chksum__mp__get_value( byte* data, long offset ); +void chksum__mp__set_value( byte* data, long offset, byte value ); + + +#define PCMP_BASELEN 4 +#define PCMP_CHKSUM 7 +#define PCMP_EXT_LEN 40 +#define PCMP_EXT_CHKSUM 42 + +#define PCMP_MINHDR 42 + +long chksum_pcmp_get_offset( byte* data, long offset ); +byte chksum_pcmp_calc_value( byte* data, long offset ); +byte chksum_pcmp_get_value( byte* data, long offset ); +void chksum_pcmp_set_value( byte* data, long offset, byte value ); + + +#define _PIR_LEN 6 +#define _PIR_CHKSUM 31 + +#define _PIR_MINHDR 32 + +long chksum__pir_get_offset( byte *data, long offset ); +byte chksum__pir_calc_value( byte* data, long offset ); +byte chksum__pir_get_value( byte* data, long offset ); +void chksum__pir_set_value( byte* data, long offset, byte value ); + + +byte bios_data[LEN_BIOS_DATA]; + + +int main( int argc, char* argv[] ) { + + FILE* stream; + long offset, tmp_offset; + byte cur_val = 0, new_val = 0; + int hits; + + + if( argc != 2 ) { + printf( "Error. Need a file-name as an argument.\n" ); + exit( EXIT_FAILURE ); + } + + if(( stream = fopen( argv[1], "rb" )) == NULL ) { + printf( "Error opening %s for reading.\n", argv[1] ); + exit( EXIT_FAILURE ); + } + if( fread( bios_data, 1, LEN_BIOS_DATA, stream ) < LEN_BIOS_DATA ) { + printf( "Error reading 64KBytes from %s.\n", argv[1] ); + fclose( stream ); + exit( EXIT_FAILURE ); + } + fclose( stream ); + + hits = 0; + offset = 0L; + while( (tmp_offset = chksum__32__get_offset( bios_data, offset )) != -1L ) { + offset = tmp_offset; + cur_val = chksum__32__get_value( bios_data, offset ); + new_val = chksum__32__calc_value( bios_data, offset ); + printf( "\n\nPCI-Bios header at: 0x%4lX\n", offset ); + printf( "Current checksum: 0x%02X\n", cur_val ); + printf( "Calculated checksum: 0x%02X ", new_val ); + hits++; + } + if( hits == 1 && cur_val != new_val ) { + printf( "Setting checksum." ); + chksum__32__set_value( bios_data, offset, new_val ); + } + if( hits >= 2 ) { + printf( "Multiple PCI headers! No checksum set." ); + } + if( hits ) { + printf( "\n" ); + } + + + hits = 0; + offset = 0L; + while( (tmp_offset = chksum__mp__get_offset( bios_data, offset )) != -1L ) { + offset = tmp_offset; + cur_val = chksum__mp__get_value( bios_data, offset ); + new_val = chksum__mp__calc_value( bios_data, offset ); + printf( "\n\nMP header at: 0x%4lX\n", offset ); + printf( "Current checksum: 0x%02X\n", cur_val ); + printf( "Calculated checksum: 0x%02X ", new_val ); + hits++; + } + if( hits == 1 && cur_val != new_val ) { + printf( "Setting checksum." ); + chksum__mp__set_value( bios_data, offset, new_val ); + } + if( hits >= 2 ) { + printf( "Warning! Multiple MP headers. No checksum set." ); + } + if( hits ) { + printf( "\n" ); + } + + + hits = 0; + offset = 0L; + while( (tmp_offset = chksum_pcmp_get_offset( bios_data, offset )) != -1L ) { + offset = tmp_offset; + cur_val = chksum_pcmp_get_value( bios_data, offset ); + new_val = chksum_pcmp_calc_value( bios_data, offset ); + printf( "\n\nPCMP header at: 0x%4lX\n", offset ); + printf( "Current checksum: 0x%02X\n", cur_val ); + printf( "Calculated checksum: 0x%02X ", new_val ); + hits++; + } + if( hits == 1 && cur_val != new_val ) { + printf( "Setting checksum." ); + chksum_pcmp_set_value( bios_data, offset, new_val ); + } + if( hits >= 2 ) { + printf( "Warning! Multiple PCMP headers. No checksum set." ); + } + if( hits ) { + printf( "\n" ); + } + + + hits = 0; + offset = 0L; + while( (tmp_offset = chksum__pir_get_offset( bios_data, offset )) != -1L ) { + offset = tmp_offset; + cur_val = chksum__pir_get_value( bios_data, offset ); + new_val = chksum__pir_calc_value( bios_data, offset ); + printf( "\n\n$PIR header at: 0x%4lX\n", offset ); + printf( "Current checksum: 0x%02X\n", cur_val ); + printf( "Calculated checksum: 0x%02X\n ", new_val ); + hits++; + } + if( hits == 1 && cur_val != new_val ) { + printf( "Setting checksum." ); + chksum__pir_set_value( bios_data, offset, new_val ); + } + if( hits >= 2 ) { + printf( "Warning! Multiple $PIR headers. No checksum set." ); + } + if( hits ) { + printf( "\n" ); + } + + + offset = 0L; + offset = chksum_bios_get_offset( bios_data, offset ); + cur_val = chksum_bios_get_value( bios_data, offset ); + new_val = chksum_bios_calc_value( bios_data, offset ); + printf( "\n\nBios checksum at: 0x%4lX\n", offset ); + printf( "Current checksum: 0x%02X\n", cur_val ); + printf( "Calculated checksum: 0x%02X ", new_val ); + if( cur_val != new_val ) { + printf( "Setting checksum." ); + chksum_bios_set_value( bios_data, offset, new_val ); + } + printf( "\n" ); + + + if(( stream = fopen( argv[1], "wb" )) == NULL ) { + printf( "Error opening %s for writing.\n", argv[1] ); + exit( EXIT_FAILURE ); + } + if( fwrite( bios_data, 1, LEN_BIOS_DATA, stream ) < LEN_BIOS_DATA ) { + printf( "Error writing 64KBytes to %s.\n", argv[1] ); + fclose( stream ); + exit( EXIT_FAILURE ); + } + fclose( stream ); + + return( EXIT_SUCCESS ); +} + + +void check( int okay, char* message ) { + + if( !okay ) { + printf( "\n\nError. %s.\n", message ); + exit( EXIT_FAILURE ); + } +} + + +long chksum_bios_get_offset( byte* data, long offset ) { + + return( BIOS_OFFSET ); +} + + +byte chksum_bios_calc_value( byte* data, long offset ) { + + int i; + byte sum; + + sum = 0; + for( i = 0; i < MAX_OFFSET; i++ ) { + sum = sum + *( data + i ); + } + sum = -sum; /* iso ensures -s + s == 0 on unsigned types */ + return( sum ); +} + + +byte chksum_bios_get_value( byte* data, long offset ) { + + return( *( data + BIOS_OFFSET ) ); +} + + +void chksum_bios_set_value( byte* data, long offset, byte value ) { + + *( data + BIOS_OFFSET ) = value; +} + + +byte chksum__32__calc_value( byte* data, long offset ) { + + int i; + int len; + byte sum; + + check( offset + _32__MINHDR <= MAX_OFFSET, "_32_ header out of bounds" ); + len = *( data + offset + _32__LEN ) << 4; + check( offset + len <= MAX_OFFSET, "_32_ header-length out of bounds" ); + sum = 0; + for( i = 0; i < len; i++ ) { + if( i != _32__CHKSUM ) { + sum = sum + *( data + offset + i ); + } + } + sum = -sum; + return( sum ); +} + + +long chksum__32__get_offset( byte* data, long offset ) { + + long result = -1L; + + offset = offset + 0x0F; + offset = offset & ~( 0x0F ); + while( offset + 16 < MAX_OFFSET ) { + offset = offset + 16; + if( *( data + offset + 0 ) == '_' && \ + *( data + offset + 1 ) == '3' && \ + *( data + offset + 2 ) == '2' && \ + *( data + offset + 3 ) == '_' ) { + result = offset; + break; + } + } + return( result ); +} + + +byte chksum__32__get_value( byte* data, long offset ) { + + check( offset + _32__CHKSUM <= MAX_OFFSET, "PCI-Bios checksum out of bounds" ); + return( *( data + offset + _32__CHKSUM ) ); +} + + +void chksum__32__set_value( byte* data, long offset, byte value ) { + + check( offset + _32__CHKSUM <= MAX_OFFSET, "PCI-Bios checksum out of bounds" ); + *( data + offset + _32__CHKSUM ) = value; +} + + +byte chksum__mp__calc_value( byte* data, long offset ) { + + int i; + int len; + byte sum; + + check( offset + _MP__MINHDR <= MAX_OFFSET, "_MP_ header out of bounds" ); + len = *( data + offset + _MP__LEN ) << 4; + check( offset + len <= MAX_OFFSET, "_MP_ header-length out of bounds" ); + sum = 0; + for( i = 0; i < len; i++ ) { + if( i != _MP__CHKSUM ) { + sum = sum + *( data + offset + i ); + } + } + sum = -sum; + return( sum ); +} + + +long chksum__mp__get_offset( byte* data, long offset ) { + + long result = -1L; + + offset = offset + 0x0F; + offset = offset & ~( 0x0F ); + while( offset + 16 < MAX_OFFSET ) { + offset = offset + 16; + if( *( data + offset + 0 ) == '_' && \ + *( data + offset + 1 ) == 'M' && \ + *( data + offset + 2 ) == 'P' && \ + *( data + offset + 3 ) == '_' ) { + result = offset; + break; + } + } + return( result ); +} + + +byte chksum__mp__get_value( byte* data, long offset ) { + + check( offset + _MP__CHKSUM <= MAX_OFFSET, "MP checksum out of bounds" ); + return( *( data + offset + _MP__CHKSUM ) ); +} + + +void chksum__mp__set_value( byte* data, long offset, byte value ) { + + check( offset + _MP__CHKSUM <= MAX_OFFSET, "MP checksum out of bounds" ); + *( data + offset + _MP__CHKSUM ) = value; +} + + +byte chksum_pcmp_calc_value( byte* data, long offset ) { + + int i; + int len; + byte sum; + + check( offset + PCMP_MINHDR <= MAX_OFFSET, "PCMP header out of bounds" ); + len = *( data + offset + PCMP_BASELEN ) + \ + ( *( data + offset + PCMP_BASELEN + 1 ) << 8 ); + check( offset + len <= MAX_OFFSET, "PCMP header-length out of bounds" ); + if( *( data + offset + PCMP_EXT_LEN ) | \ + *( data + offset + PCMP_EXT_LEN + 1 ) | \ + *( data + offset + PCMP_EXT_CHKSUM ) ) { + check( 0, "PCMP header indicates extended tables (unsupported)" ); + } + sum = 0; + for( i = 0; i < len; i++ ) { + if( i != PCMP_CHKSUM ) { + sum = sum + *( data + offset + i ); + } + } + sum = -sum; + return( sum ); +} + + +long chksum_pcmp_get_offset( byte* data, long offset ) { + + long result = -1L; + + offset = offset + 0x0F; + offset = offset & ~( 0x0F ); + while( offset + 16 < MAX_OFFSET ) { + offset = offset + 16; + if( *( data + offset + 0 ) == 'P' && \ + *( data + offset + 1 ) == 'C' && \ + *( data + offset + 2 ) == 'M' && \ + *( data + offset + 3 ) == 'P' ) { + result = offset; + break; + } + } + return( result ); +} + + +byte chksum_pcmp_get_value( byte* data, long offset ) { + + check( offset + PCMP_CHKSUM <= MAX_OFFSET, "PCMP checksum out of bounds" ); + return( *( data + offset + PCMP_CHKSUM ) ); +} + + +void chksum_pcmp_set_value( byte* data, long offset, byte value ) { + + check( offset + PCMP_CHKSUM <= MAX_OFFSET, "PCMP checksum out of bounds" ); + *( data + offset + PCMP_CHKSUM ) = value; +} + + +byte chksum__pir_calc_value( byte* data, long offset ) { + + int i; + int len; + byte sum; + + check( offset + _PIR_MINHDR <= MAX_OFFSET, "$PIR header out of bounds" ); + len = *( data + offset + _PIR_LEN ) + \ + ( *( data + offset + _PIR_LEN + 1 ) << 8 ); + check( offset + len <= MAX_OFFSET, "$PIR header-length out of bounds" ); + sum = 0; + for( i = 0; i < len; i++ ) { + if( i != _PIR_CHKSUM ) { + sum = sum + *( data + offset + i ); + } + } + sum = -sum; + return( sum ); +} + + +long chksum__pir_get_offset( byte* data, long offset ) { + + long result = -1L; + + offset = offset + 0x0F; + offset = offset & ~( 0x0F ); + while( offset + 16 < MAX_OFFSET ) { + offset = offset + 16; + if( *( data + offset + 0 ) == '$' && \ + *( data + offset + 1 ) == 'P' && \ + *( data + offset + 2 ) == 'I' && \ + *( data + offset + 3 ) == 'R' ) { + result = offset; + break; + } + } + return( result ); +} + + +byte chksum__pir_get_value( byte* data, long offset ) { + + check( offset + _PIR_CHKSUM <= MAX_OFFSET, "$PIR checksum out of bounds" ); + return( *( data + offset + _PIR_CHKSUM ) ); +} + + +void chksum__pir_set_value( byte* data, long offset, byte value ) { + + check( offset + _PIR_CHKSUM <= MAX_OFFSET, "$PIR checksum out of bounds" ); + *( data + offset + _PIR_CHKSUM ) = value; +} +