14d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/* 24d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * $Id$ 34d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * 44d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * This library is free software; you can redistribute it and/or 54d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * modify it under the terms of the GNU Lesser General Public 64d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * License as published by the Free Software Foundation; either 74d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * version 2 of the License, or (at your option) any later version. 84d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * 94d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * This library is distributed in the hope that it will be useful, 104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * but WITHOUT ANY WARRANTY; without even the implied warranty of 114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * Lesser General Public License for more details. 134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * 144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * You should have received a copy of the GNU Lesser General Public 154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * License along with this library; if not, write to the Free Software 164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima */ 184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/* biossums.c --- written by Eike W. for the Bochs BIOS */ 204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#include <stdlib.h> 224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#include <stdio.h> 234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#include <string.h> 244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimatypedef unsigned char byte; 264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid check( int value, char* message ); 284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define LEN_BIOS_DATA 0x10000 304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define MAX_OFFSET (LEN_BIOS_DATA - 1) 314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define BIOS_OFFSET 0xFFFF 344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong chksum_bios_get_offset( byte* data, long offset ); 364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum_bios_calc_value( byte* data, long offset ); 374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum_bios_get_value( byte* data, long offset ); 384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid chksum_bios_set_value( byte* data, long offset, byte value ); 394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define _32__LEN 9 424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define _32__CHKSUM 10 434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define _32__MINHDR 16 454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong chksum__32__get_offset( byte* data, long offset ); 474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum__32__calc_value( byte* data, long offset ); 484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum__32__get_value( byte* data, long offset ); 494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid chksum__32__set_value( byte* data, long offset, byte value ); 504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define _MP__LEN 8 534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define _MP__CHKSUM 10 544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define _MP__MINHDR 16 564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong chksum__mp__get_offset( byte* data, long offset ); 584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum__mp__calc_value( byte* data, long offset ); 594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum__mp__get_value( byte* data, long offset ); 604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid chksum__mp__set_value( byte* data, long offset, byte value ); 614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define PCMP_BASELEN 4 644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define PCMP_CHKSUM 7 654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define PCMP_EXT_LEN 40 664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define PCMP_EXT_CHKSUM 42 674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define PCMP_MINHDR 42 694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong chksum_pcmp_get_offset( byte* data, long offset ); 714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum_pcmp_calc_value( byte* data, long offset ); 724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum_pcmp_get_value( byte* data, long offset ); 734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid chksum_pcmp_set_value( byte* data, long offset, byte value ); 744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define _PIR_LEN 6 774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define _PIR_CHKSUM 31 784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define _PIR_MINHDR 32 804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong chksum__pir_get_offset( byte *data, long offset ); 824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum__pir_calc_value( byte* data, long offset ); 834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum__pir_get_value( byte* data, long offset ); 844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid chksum__pir_set_value( byte* data, long offset, byte value ); 854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte bios_data[LEN_BIOS_DATA]; 884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong bios_len; 894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint main(int argc, char* argv[]) { 924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima FILE* stream; 944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima long offset, tmp_offset; 954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima byte cur_val = 0, new_val = 0; 964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int arg = 1, hits, pad = 0; 974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if ((argc == 3) && (!strcmp(argv[1], "-pad"))) { 1004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima pad = 1; 1014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima arg = 2; 1024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } else if (argc != 2) { 1034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("Error. Need a file-name as an argument.\n"); 1044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima exit(EXIT_FAILURE); 1054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 1064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima memset(bios_data, 0xff, LEN_BIOS_DATA); 1074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if ((stream = fopen(argv[arg], "rb")) == NULL) { 1094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("Error opening %s for reading.\n", argv[arg]); 1104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima exit(EXIT_FAILURE); 1114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 1124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima bios_len = fread(bios_data, 1, LEN_BIOS_DATA, stream); 1134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if ((bios_len < LEN_BIOS_DATA) && (pad == 0)) { 1144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("Error reading 64KBytes from %s.\n", argv[arg]); 1154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima fclose(stream); 1164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima exit(EXIT_FAILURE); 1174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 1184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima fclose(stream); 1194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (pad == 1) goto write_bios; 1204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima hits = 0; 1224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = 0L; 1234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima while( (tmp_offset = chksum__32__get_offset( bios_data, offset )) != -1L ) { 1244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = tmp_offset; 1254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima cur_val = chksum__32__get_value( bios_data, offset ); 1264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima new_val = chksum__32__calc_value( bios_data, offset ); 1274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "\n\nPCI-Bios header at: 0x%4lX\n", offset ); 1284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Current checksum: 0x%02X\n", cur_val ); 1294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Calculated checksum: 0x%02X ", new_val ); 1304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima hits++; 1314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 1324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( hits == 1 && cur_val != new_val ) { 1334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Setting checksum." ); 1344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima chksum__32__set_value( bios_data, offset, new_val ); 1354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 1364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( hits >= 2 ) { 1374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Multiple PCI headers! No checksum set." ); 1384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 1394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( hits ) { 1404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "\n" ); 1414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 1424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima hits = 0; 1454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = 0L; 1464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima while( (tmp_offset = chksum__mp__get_offset( bios_data, offset )) != -1L ) { 1474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = tmp_offset; 1484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima cur_val = chksum__mp__get_value( bios_data, offset ); 1494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima new_val = chksum__mp__calc_value( bios_data, offset ); 1504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "\n\nMP header at: 0x%4lX\n", offset ); 1514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Current checksum: 0x%02X\n", cur_val ); 1524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Calculated checksum: 0x%02X ", new_val ); 1534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima hits++; 1544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 1554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( hits == 1 && cur_val != new_val ) { 1564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Setting checksum." ); 1574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima chksum__mp__set_value( bios_data, offset, new_val ); 1584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 1594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( hits >= 2 ) { 1604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Warning! Multiple MP headers. No checksum set." ); 1614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 1624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( hits ) { 1634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "\n" ); 1644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 1654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima hits = 0; 1684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = 0L; 1694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima while( (tmp_offset = chksum_pcmp_get_offset( bios_data, offset )) != -1L ) { 1704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = tmp_offset; 1714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima cur_val = chksum_pcmp_get_value( bios_data, offset ); 1724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima new_val = chksum_pcmp_calc_value( bios_data, offset ); 1734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "\n\nPCMP header at: 0x%4lX\n", offset ); 1744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Current checksum: 0x%02X\n", cur_val ); 1754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Calculated checksum: 0x%02X ", new_val ); 1764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima hits++; 1774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 1784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( hits == 1 && cur_val != new_val ) { 1794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Setting checksum." ); 1804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima chksum_pcmp_set_value( bios_data, offset, new_val ); 1814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 1824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( hits >= 2 ) { 1834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Warning! Multiple PCMP headers. No checksum set." ); 1844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 1854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( hits ) { 1864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "\n" ); 1874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 1884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima hits = 0; 1914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = 0L; 1924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima while( (tmp_offset = chksum__pir_get_offset( bios_data, offset )) != -1L ) { 1934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = tmp_offset; 1944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima cur_val = chksum__pir_get_value( bios_data, offset ); 1954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima new_val = chksum__pir_calc_value( bios_data, offset ); 1964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "\n\n$PIR header at: 0x%4lX\n", offset ); 1974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Current checksum: 0x%02X\n", cur_val ); 1984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Calculated checksum: 0x%02X\n ", new_val ); 1994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima hits++; 2004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 2014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( hits == 1 && cur_val != new_val ) { 2024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Setting checksum." ); 2034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima chksum__pir_set_value( bios_data, offset, new_val ); 2044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 2054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( hits >= 2 ) { 2064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Warning! Multiple $PIR headers. No checksum set." ); 2074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 2084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( hits ) { 2094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "\n" ); 2104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 2114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = 0L; 2144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = chksum_bios_get_offset( bios_data, offset ); 2154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima cur_val = chksum_bios_get_value( bios_data, offset ); 2164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima new_val = chksum_bios_calc_value( bios_data, offset ); 2174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "\n\nBios checksum at: 0x%4lX\n", offset ); 2184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Current checksum: 0x%02X\n", cur_val ); 2194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Calculated checksum: 0x%02X ", new_val ); 2204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( cur_val != new_val ) { 2214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "Setting checksum." ); 2224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima chksum_bios_set_value( bios_data, offset, new_val ); 2234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 2244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf( "\n" ); 2254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimawrite_bios: 2274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if ((stream = fopen(argv[arg], "wb")) == NULL) { 2284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("Error opening %s for writing.\n", argv[arg]); 2294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima exit(EXIT_FAILURE); 2304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 2314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (fwrite(bios_data, 1, LEN_BIOS_DATA, stream) < LEN_BIOS_DATA) { 2324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("Error writing 64KBytes to %s.\n", argv[arg]); 2334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima fclose(stream); 2344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima exit(EXIT_FAILURE); 2354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 2364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima fclose(stream); 2374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return(EXIT_SUCCESS); 2394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 2404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid check(int okay, char* message) { 2434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (!okay) { 2454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("\n\nError. %s.\n", message); 2464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima exit(EXIT_FAILURE); 2474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 2484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 2494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong chksum_bios_get_offset( byte* data, long offset ) { 2524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return( BIOS_OFFSET ); 2544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 2554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum_bios_calc_value( byte* data, long offset ) { 2584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int i; 2604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima byte sum; 2614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sum = 0; 2634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima for( i = 0; i < MAX_OFFSET; i++ ) { 2644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sum = sum + *( data + i ); 2654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 2664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sum = -sum; /* iso ensures -s + s == 0 on unsigned types */ 2674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return( sum ); 2684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 2694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum_bios_get_value( byte* data, long offset ) { 2724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return( *( data + BIOS_OFFSET ) ); 2744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 2754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid chksum_bios_set_value( byte* data, long offset, byte value ) { 2784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + BIOS_OFFSET ) = value; 2804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 2814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum__32__calc_value( byte* data, long offset ) { 2844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int i; 2864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int len; 2874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima byte sum; 2884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( offset + _32__MINHDR <= MAX_OFFSET, "_32_ header out of bounds" ); 2904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima len = *( data + offset + _32__LEN ) << 4; 2914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( offset + len <= MAX_OFFSET, "_32_ header-length out of bounds" ); 2924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sum = 0; 2934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima for( i = 0; i < len; i++ ) { 2944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( i != _32__CHKSUM ) { 2954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sum = sum + *( data + offset + i ); 2964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 2974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 2984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sum = -sum; 2994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return( sum ); 3004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 3014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong chksum__32__get_offset( byte* data, long offset ) { 3044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima long result = -1L; 3064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = offset + 0x0F; 3084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = offset & ~( 0x0F ); 3094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima while( offset + 16 < MAX_OFFSET ) { 3104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = offset + 16; 3114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( *( data + offset + 0 ) == '_' && \ 3124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + 1 ) == '3' && \ 3134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + 2 ) == '2' && \ 3144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + 3 ) == '_' ) { 3154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima result = offset; 3164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima break; 3174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 3184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 3194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return( result ); 3204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 3214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum__32__get_value( byte* data, long offset ) { 3244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( offset + _32__CHKSUM <= MAX_OFFSET, "PCI-Bios checksum out of bounds" ); 3264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return( *( data + offset + _32__CHKSUM ) ); 3274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 3284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid chksum__32__set_value( byte* data, long offset, byte value ) { 3314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( offset + _32__CHKSUM <= MAX_OFFSET, "PCI-Bios checksum out of bounds" ); 3334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + _32__CHKSUM ) = value; 3344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 3354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum__mp__calc_value( byte* data, long offset ) { 3384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int i; 3404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int len; 3414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima byte sum; 3424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( offset + _MP__MINHDR <= MAX_OFFSET, "_MP_ header out of bounds" ); 3444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima len = *( data + offset + _MP__LEN ) << 4; 3454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( offset + len <= MAX_OFFSET, "_MP_ header-length out of bounds" ); 3464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sum = 0; 3474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima for( i = 0; i < len; i++ ) { 3484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( i != _MP__CHKSUM ) { 3494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sum = sum + *( data + offset + i ); 3504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 3514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 3524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sum = -sum; 3534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return( sum ); 3544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 3554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong chksum__mp__get_offset( byte* data, long offset ) { 3584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima long result = -1L; 3604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = offset + 0x0F; 3624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = offset & ~( 0x0F ); 3634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima while( offset + 16 < MAX_OFFSET ) { 3644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = offset + 16; 3654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( *( data + offset + 0 ) == '_' && \ 3664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + 1 ) == 'M' && \ 3674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + 2 ) == 'P' && \ 3684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + 3 ) == '_' ) { 3694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima result = offset; 3704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima break; 3714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 3724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 3734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return( result ); 3744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 3754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum__mp__get_value( byte* data, long offset ) { 3784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( offset + _MP__CHKSUM <= MAX_OFFSET, "MP checksum out of bounds" ); 3804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return( *( data + offset + _MP__CHKSUM ) ); 3814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 3824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid chksum__mp__set_value( byte* data, long offset, byte value ) { 3854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( offset + _MP__CHKSUM <= MAX_OFFSET, "MP checksum out of bounds" ); 3874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + _MP__CHKSUM ) = value; 3884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 3894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum_pcmp_calc_value( byte* data, long offset ) { 3924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int i; 3944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int len; 3954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima byte sum; 3964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( offset + PCMP_MINHDR <= MAX_OFFSET, "PCMP header out of bounds" ); 3984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima len = *( data + offset + PCMP_BASELEN ) + \ 3994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima ( *( data + offset + PCMP_BASELEN + 1 ) << 8 ); 4004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( offset + len <= MAX_OFFSET, "PCMP header-length out of bounds" ); 4014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( *( data + offset + PCMP_EXT_LEN ) | \ 4024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + PCMP_EXT_LEN + 1 ) | \ 4034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + PCMP_EXT_CHKSUM ) ) { 4044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( 0, "PCMP header indicates extended tables (unsupported)" ); 4054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 4064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sum = 0; 4074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima for( i = 0; i < len; i++ ) { 4084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( i != PCMP_CHKSUM ) { 4094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sum = sum + *( data + offset + i ); 4104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 4114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 4124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sum = -sum; 4134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return( sum ); 4144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 4154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong chksum_pcmp_get_offset( byte* data, long offset ) { 4184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima long result = -1L; 4204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = offset + 0x0F; 4224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = offset & ~( 0x0F ); 4234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima while( offset + 16 < MAX_OFFSET ) { 4244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = offset + 16; 4254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( *( data + offset + 0 ) == 'P' && \ 4264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + 1 ) == 'C' && \ 4274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + 2 ) == 'M' && \ 4284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + 3 ) == 'P' ) { 4294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima result = offset; 4304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima break; 4314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 4324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 4334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return( result ); 4344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 4354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum_pcmp_get_value( byte* data, long offset ) { 4384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( offset + PCMP_CHKSUM <= MAX_OFFSET, "PCMP checksum out of bounds" ); 4404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return( *( data + offset + PCMP_CHKSUM ) ); 4414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 4424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid chksum_pcmp_set_value( byte* data, long offset, byte value ) { 4454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( offset + PCMP_CHKSUM <= MAX_OFFSET, "PCMP checksum out of bounds" ); 4474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + PCMP_CHKSUM ) = value; 4484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 4494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum__pir_calc_value( byte* data, long offset ) { 4524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int i; 4544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int len; 4554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima byte sum; 4564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( offset + _PIR_MINHDR <= MAX_OFFSET, "$PIR header out of bounds" ); 4584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima len = *( data + offset + _PIR_LEN ) + \ 4594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima ( *( data + offset + _PIR_LEN + 1 ) << 8 ); 4604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( offset + len <= MAX_OFFSET, "$PIR header-length out of bounds" ); 4614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sum = 0; 4624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima for( i = 0; i < len; i++ ) { 4634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( i != _PIR_CHKSUM ) { 4644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sum = sum + *( data + offset + i ); 4654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 4664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 4674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sum = -sum; 4684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return( sum ); 4694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 4704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong chksum__pir_get_offset( byte* data, long offset ) { 4734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima long result = -1L; 4754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = offset + 0x0F; 4774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = offset & ~( 0x0F ); 4784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima while( offset + 16 < MAX_OFFSET ) { 4794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima offset = offset + 16; 4804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if( *( data + offset + 0 ) == '$' && \ 4814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + 1 ) == 'P' && \ 4824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + 2 ) == 'I' && \ 4834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + 3 ) == 'R' ) { 4844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima result = offset; 4854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima break; 4864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 4874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 4884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return( result ); 4894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 4904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum__pir_get_value( byte* data, long offset ) { 4934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( offset + _PIR_CHKSUM <= MAX_OFFSET, "$PIR checksum out of bounds" ); 4954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return( *( data + offset + _PIR_CHKSUM ) ); 4964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 4974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid chksum__pir_set_value( byte* data, long offset, byte value ) { 5004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 5014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima check( offset + _PIR_CHKSUM <= MAX_OFFSET, "$PIR checksum out of bounds" ); 5024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *( data + offset + _PIR_CHKSUM ) = value; 5034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 5044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 505