14d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/* biossums.c  --- written by Eike W. for the Bochs BIOS */
24d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/* adapted for the LGPL'd VGABIOS by vruppert */
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#include <stdlib.h>
194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#include <stdio.h>
204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#include <string.h>
214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimatypedef unsigned char byte;
234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid check( int value, char* message );
254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define MAX_BIOS_DATA 0x10000
274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong chksum_bios_get_offset( byte* data, long offset );
294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum_bios_calc_value( byte* data, long offset );
304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum_bios_get_value(  byte* data, long offset );
314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid chksum_bios_set_value(  byte* data, long offset, byte value );
324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define PMID_LEN        20
344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define PMID_CHKSUM     19
354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong chksum_pmid_get_offset( byte* data, long offset );
374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum_pmid_calc_value( byte* data, long offset );
384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum_pmid_get_value(  byte* data, long offset );
394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid chksum_pmid_set_value(  byte* data, long offset, byte value );
404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define PCIR_LEN        24
424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong chksum_pcir_get_offset( byte* data, long offset );
444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte bios_data[MAX_BIOS_DATA];
474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong bios_len;
484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint main(int argc, char* argv[])
514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{
524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  FILE* stream;
534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  long  offset, tmp_offset, pcir_offset;
544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  byte  bios_len_byte, cur_val = 0, new_val = 0;
554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  int   hits, modified;
564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (argc != 2) {
584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    printf( "Error. Need a file-name as an argument.\n" );
594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    exit( EXIT_FAILURE );
604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ((stream = fopen(argv[1], "rb")) == NULL) {
634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    printf("Error opening %s for reading.\n", argv[1]);
644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    exit(EXIT_FAILURE);
654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  memset(bios_data, 0, MAX_BIOS_DATA);
674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bios_len = fread(bios_data, 1, MAX_BIOS_DATA, stream);
684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (bios_len > MAX_BIOS_DATA) {
694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    printf("Error reading max. 65536 Bytes from %s.\n", argv[1]);
704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    fclose(stream);
714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    exit(EXIT_FAILURE);
724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  fclose(stream);
744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  modified = 0;
754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (bios_len < 0x8000) {
764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    bios_len = 0x8000;
774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    modified = 1;
784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } else if ((bios_len & 0x1FF) != 0) {
794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    bios_len = (bios_len + 0x200) & ~0x1FF;
804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    modified = 1;
814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  bios_len_byte = (byte)(bios_len / 512);
834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (bios_len_byte != bios_data[2]) {
844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (modified == 0) {
854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      bios_len += 0x200;
864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    bios_data[2] = (byte)(bios_len / 512);
884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    modified = 1;
894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  hits   = 0;
924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  offset = 0L;
934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  while( (tmp_offset = chksum_pmid_get_offset( bios_data, offset )) != -1L ) {
944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    offset  = tmp_offset;
954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    cur_val = chksum_pmid_get_value(  bios_data, offset );
964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    new_val = chksum_pmid_calc_value( bios_data, offset );
974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    printf( "\nPMID entry at: 0x%4lX\n", offset  );
984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    printf( "Current checksum:     0x%02X\n",   cur_val );
994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    printf( "Calculated checksum:  0x%02X  ",   new_val );
1004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    hits++;
1014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
1024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if ((hits == 1) && (cur_val != new_val)) {
1034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    printf("Setting checksum.");
1044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    chksum_pmid_set_value( bios_data, offset, new_val );
1054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (modified == 0) {
1064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      bios_len += 0x200;
1074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      bios_data[2]++;
1084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
1094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    modified = 1;
1104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
1114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (hits >= 2) {
1124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    printf( "Multiple PMID entries! No checksum set." );
1134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
1144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (hits) {
1154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    printf("\n");
1164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
1174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  offset = 0L;
1194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  pcir_offset = chksum_pcir_get_offset( bios_data, offset );
1204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (pcir_offset != -1L) {
1214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (bios_data[pcir_offset + 16] != bios_data[2]) {
1224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      bios_data[pcir_offset + 16] = bios_data[2];
1234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (modified == 0) {
1244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        bios_len += 0x200;
1254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        bios_data[2]++;
1264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        bios_data[pcir_offset + 16]++;
1274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
1284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      modified = 1;
1294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
1304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
1314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  offset  = 0L;
1334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  do {
1344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    offset  = chksum_bios_get_offset(bios_data, offset);
1354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    cur_val = chksum_bios_get_value(bios_data, offset);
1364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    new_val = chksum_bios_calc_value(bios_data, offset);
1374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ((cur_val != new_val) && (modified == 0)) {
1384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      bios_len += 0x200;
1394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      bios_data[2]++;
1404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (pcir_offset != -1L) {
1414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        bios_data[pcir_offset + 16]++;
1424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
1434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      modified = 1;
1444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    } else {
1454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      printf("\nBios checksum at:   0x%4lX\n", offset);
1464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      printf("Current checksum:     0x%02X\n", cur_val);
1474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      printf("Calculated checksum:  0x%02X  ", new_val);
1484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      if (cur_val != new_val) {
1494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        printf("Setting checksum.");
1504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        chksum_bios_set_value(bios_data, offset, new_val);
1514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        cur_val = new_val;
1524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        modified = 1;
1534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      }
1544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      printf( "\n" );
1554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
1564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  } while (cur_val != new_val);
1574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if (modified == 1) {
1594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if ((stream = fopen( argv[1], "wb")) == NULL) {
1604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      printf("Error opening %s for writing.\n", argv[1]);
1614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      exit(EXIT_FAILURE);
1624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
1634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if (fwrite(bios_data, 1, bios_len, stream) < bios_len) {
1644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      printf("Error writing %d KBytes to %s.\n", bios_len / 1024, argv[1]);
1654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      fclose(stream);
1664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      exit(EXIT_FAILURE);
1674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
1684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    fclose(stream);
1694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
1704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return (EXIT_SUCCESS);
1724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
1734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid check( int okay, char* message ) {
1764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  if( !okay ) {
1784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    printf( "\n\nError. %s.\n", message );
1794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    exit( EXIT_FAILURE );
1804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
1814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
1824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong chksum_bios_get_offset( byte* data, long offset ) {
1854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return (bios_len - 1);
1874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
1884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum_bios_calc_value( byte* data, long offset ) {
1914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  int   i;
1934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  byte  sum;
1944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
1954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sum = 0;
1964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  for( i = 0; i < offset; i++ ) {
1974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    sum = sum + *( data + i );
1984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
1994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sum = -sum;          /* iso ensures -s + s == 0 on unsigned types */
2004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return( sum );
2014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
2024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum_bios_get_value( byte* data, long offset ) {
2054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return( *( data + offset ) );
2074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
2084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid chksum_bios_set_value( byte* data, long offset, byte value ) {
2114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  *( data + offset ) = value;
2134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
2144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum_pmid_calc_value( byte* data, long offset ) {
2174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  int           i;
2194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  int           len;
2204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  byte sum;
2214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  len = PMID_LEN;
2234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  check((offset + len) <= (bios_len - 1), "PMID entry length out of bounds" );
2244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sum = 0;
2254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  for( i = 0; i < len; i++ ) {
2264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if( i != PMID_CHKSUM ) {
2274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      sum = sum + *( data + offset + i );
2284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
2294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
2304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  sum = -sum;
2314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return( sum );
2324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
2334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong chksum_pmid_get_offset( byte* data, long offset ) {
2364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  long result = -1L;
2384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  while ((offset + PMID_LEN) < (bios_len - 1)) {
2404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    offset = offset + 1;
2414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if( *( data + offset + 0 ) == 'P' && \
2424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        *( data + offset + 1 ) == 'M' && \
2434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        *( data + offset + 2 ) == 'I' && \
2444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        *( data + offset + 3 ) == 'D' ) {
2454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      result = offset;
2464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
2474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
2484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
2494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return( result );
2504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
2514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimabyte chksum_pmid_get_value( byte* data, long offset ) {
2544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  check((offset + PMID_CHKSUM) <= (bios_len - 1), "PMID checksum out of bounds" );
2564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return(  *( data + offset + PMID_CHKSUM ) );
2574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
2584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid chksum_pmid_set_value( byte* data, long offset, byte value ) {
2614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  check((offset + PMID_CHKSUM) <= (bios_len - 1), "PMID checksum out of bounds" );
2634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  *( data + offset + PMID_CHKSUM ) = value;
2644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
2654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong chksum_pcir_get_offset( byte* data, long offset ) {
2684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  long result = -1L;
2704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima
2714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  while ((offset + PCIR_LEN) < (bios_len - 1)) {
2724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    offset = offset + 1;
2734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    if( *( data + offset + 0 ) == 'P' && \
2744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        *( data + offset + 1 ) == 'C' && \
2754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        *( data + offset + 2 ) == 'I' && \
2764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima        *( data + offset + 3 ) == 'R' ) {
2774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      result = offset;
2784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima      break;
2794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima    }
2804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  }
2814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima  return( result );
2824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima}
283