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