xref: /netbsd/sys/arch/i386/stand/genprom/genprom.c (revision c4a72b64)
1 /*	$NetBSD: genprom.c,v 1.4 2002/07/20 08:36:18 grant Exp $	 */
2 
3 /*
4  * mainly from netbsd:sys/arch/i386/netboot/genprom.c
5  */
6 
7 /*
8  * Read a binary image of a bios extension, generate the
9  * appropriate block count and checksum and write them
10  * into the rom image (replacing 2nd and 5th bytes)
11  * The binary image should be sized before being filtered
12  * through this routine.
13  */
14 
15 #include <stdio.h>
16 #include <err.h>
17 #include <string.h>
18 
19 #define PROM_SIZE 0x10000	/* max */
20 
21 int
22 main(argc, argv)
23 	int             argc;
24 	char          **argv;
25 {
26 	char            w[PROM_SIZE];
27 	int             i, sum;
28 	int             romsize;
29 	unsigned short  ck16;
30 
31 	if (argc > 1) {
32 		if (sscanf(argv[1], "%d", &romsize) != 1) {
33 			errx(1, "bad arg");
34 		}
35 	} else {
36 		errx(1, "arg: romsize / bytes");
37 	}
38 
39 	memset(w, 0x0, PROM_SIZE);
40 	i = fread(w, 1, PROM_SIZE, stdin);
41 
42 	fprintf(stderr, "bios extension size: %d (0x%x), read %d bytes\n",
43 		romsize, romsize, i);
44 
45 	if (i > romsize)
46 		errx(1, "read longer than expected");
47 
48 	w[2] = romsize / 512;	/* BIOS extension size */
49 
50 	i = w[0x18] + (w[0x19] << 8);	/* if this is a PCI ROM, this is the
51 					 * offset to the "PCI data structure" */
52 	if ((i < romsize - 0x18) && (w[i] == 'P') && (w[i + 1] == 'C')
53 	    && (w[i + 2] == 'I') && (w[i + 3] == 'R')) {
54 		fprintf(stderr, "PCI Data Structure found\n");
55 		w[i + 0x10] = romsize / 512;	/* BIOS extension size again */
56 	}
57 	for (sum = 0, i = 0; i < romsize; i++) {
58 		sum += w[i];
59 	}
60 	w[5] = -sum;		/* left free for checksum adjustment */
61 
62 	/* calculate CRC as used by PROM programmers */
63 	for (ck16 = 0, i = 0; i < romsize; i++)
64 		ck16 += (unsigned char) w[i];
65 	fprintf(stderr, "ROM CRC: 0x%04x\n", ck16);
66 
67 	fwrite(w, 1, romsize, stdout);
68 	return (0);
69 }
70