xref: /aosp_15_r20/external/flashrom/print.c (revision 0d6140be3aa665ecc836e8907834fcd3e3b018fc)
1*0d6140beSAndroid Build Coastguard Worker /*
2*0d6140beSAndroid Build Coastguard Worker  * This file is part of the flashrom project.
3*0d6140beSAndroid Build Coastguard Worker  *
4*0d6140beSAndroid Build Coastguard Worker  * Copyright (C) 2009 Uwe Hermann <[email protected]>
5*0d6140beSAndroid Build Coastguard Worker  * Copyright (C) 2009 Carl-Daniel Hailfinger
6*0d6140beSAndroid Build Coastguard Worker  * Copyright (C) 2011-2013 Stefan Tauner
7*0d6140beSAndroid Build Coastguard Worker  *
8*0d6140beSAndroid Build Coastguard Worker  * This program is free software; you can redistribute it and/or modify
9*0d6140beSAndroid Build Coastguard Worker  * it under the terms of the GNU General Public License as published by
10*0d6140beSAndroid Build Coastguard Worker  * the Free Software Foundation; either version 2 of the License, or
11*0d6140beSAndroid Build Coastguard Worker  * (at your option) any later version.
12*0d6140beSAndroid Build Coastguard Worker  *
13*0d6140beSAndroid Build Coastguard Worker  * This program is distributed in the hope that it will be useful,
14*0d6140beSAndroid Build Coastguard Worker  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*0d6140beSAndroid Build Coastguard Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*0d6140beSAndroid Build Coastguard Worker  * GNU General Public License for more details.
17*0d6140beSAndroid Build Coastguard Worker  */
18*0d6140beSAndroid Build Coastguard Worker 
19*0d6140beSAndroid Build Coastguard Worker #include <stdio.h>
20*0d6140beSAndroid Build Coastguard Worker #include <string.h>
21*0d6140beSAndroid Build Coastguard Worker #include <stdlib.h>
22*0d6140beSAndroid Build Coastguard Worker #include <stddef.h>
23*0d6140beSAndroid Build Coastguard Worker #if HAVE_UTSNAME == 1
24*0d6140beSAndroid Build Coastguard Worker #include <sys/utsname.h>
25*0d6140beSAndroid Build Coastguard Worker #endif
26*0d6140beSAndroid Build Coastguard Worker #if IS_WINDOWS
27*0d6140beSAndroid Build Coastguard Worker #include <windows.h>
28*0d6140beSAndroid Build Coastguard Worker #undef min
29*0d6140beSAndroid Build Coastguard Worker #undef max
30*0d6140beSAndroid Build Coastguard Worker #endif
31*0d6140beSAndroid Build Coastguard Worker 
32*0d6140beSAndroid Build Coastguard Worker #include "flash.h"
33*0d6140beSAndroid Build Coastguard Worker #include "programmer.h"
34*0d6140beSAndroid Build Coastguard Worker 
test_state_to_text(enum test_state test_state)35*0d6140beSAndroid Build Coastguard Worker static const char *test_state_to_text(enum test_state test_state)
36*0d6140beSAndroid Build Coastguard Worker {
37*0d6140beSAndroid Build Coastguard Worker 	switch (test_state) {
38*0d6140beSAndroid Build Coastguard Worker 	case OK: return "OK";
39*0d6140beSAndroid Build Coastguard Worker 	case BAD: return "Not working";
40*0d6140beSAndroid Build Coastguard Worker 	case NA: return "N/A";
41*0d6140beSAndroid Build Coastguard Worker 	case DEP: return "Config-dependent";
42*0d6140beSAndroid Build Coastguard Worker 	case NT:
43*0d6140beSAndroid Build Coastguard Worker 	default: return "Untested";
44*0d6140beSAndroid Build Coastguard Worker 	}
45*0d6140beSAndroid Build Coastguard Worker }
46*0d6140beSAndroid Build Coastguard Worker 
print_supported_chips(void)47*0d6140beSAndroid Build Coastguard Worker static int print_supported_chips(void)
48*0d6140beSAndroid Build Coastguard Worker {
49*0d6140beSAndroid Build Coastguard Worker 	const char *delim = "/";
50*0d6140beSAndroid Build Coastguard Worker 	const int mintoklen = 5;
51*0d6140beSAndroid Build Coastguard Worker 	const int border = 2;
52*0d6140beSAndroid Build Coastguard Worker 	int i, chipcount = 0;
53*0d6140beSAndroid Build Coastguard Worker 	int maxvendorlen = strlen("Vendor") + 1;
54*0d6140beSAndroid Build Coastguard Worker 	int maxchiplen = strlen("Device") + 1;
55*0d6140beSAndroid Build Coastguard Worker 	int maxtypelen = strlen("Type") + 1;
56*0d6140beSAndroid Build Coastguard Worker 	const struct flashchip *chip;
57*0d6140beSAndroid Build Coastguard Worker 	char *s;
58*0d6140beSAndroid Build Coastguard Worker 	char *ven, *dev;
59*0d6140beSAndroid Build Coastguard Worker 	char *tmpven, *tmpdev, *tmpven_save, *tmpdev_save;
60*0d6140beSAndroid Build Coastguard Worker 	int tmpvenlen, tmpdevlen, curvenlen, curdevlen;
61*0d6140beSAndroid Build Coastguard Worker 
62*0d6140beSAndroid Build Coastguard Worker 	/* calculate maximum column widths and by iterating over all chips */
63*0d6140beSAndroid Build Coastguard Worker 	for (chip = flashchips; chip->name != NULL; chip++) {
64*0d6140beSAndroid Build Coastguard Worker 		/* Ignore generic entries. */
65*0d6140beSAndroid Build Coastguard Worker 		if (!strncmp(chip->vendor, "Unknown", 7) ||
66*0d6140beSAndroid Build Coastguard Worker 		    !strncmp(chip->vendor, "Programmer", 10) ||
67*0d6140beSAndroid Build Coastguard Worker 		    !strncmp(chip->name, "unknown", 7))
68*0d6140beSAndroid Build Coastguard Worker 			continue;
69*0d6140beSAndroid Build Coastguard Worker 		chipcount++;
70*0d6140beSAndroid Build Coastguard Worker 
71*0d6140beSAndroid Build Coastguard Worker 		/* Find maximum vendor length (respecting line splitting). */
72*0d6140beSAndroid Build Coastguard Worker 		tmpven = (char *)chip->vendor;
73*0d6140beSAndroid Build Coastguard Worker 		do {
74*0d6140beSAndroid Build Coastguard Worker 			/* and take minimum token lengths into account */
75*0d6140beSAndroid Build Coastguard Worker 			tmpvenlen = 0;
76*0d6140beSAndroid Build Coastguard Worker 			do {
77*0d6140beSAndroid Build Coastguard Worker 				tmpvenlen += strcspn(tmpven, delim);
78*0d6140beSAndroid Build Coastguard Worker 				/* skip to the address after the first token */
79*0d6140beSAndroid Build Coastguard Worker 				tmpven += tmpvenlen;
80*0d6140beSAndroid Build Coastguard Worker 				if (tmpven[0] == '\0')
81*0d6140beSAndroid Build Coastguard Worker 					break;
82*0d6140beSAndroid Build Coastguard Worker 				tmpven++;
83*0d6140beSAndroid Build Coastguard Worker 			} while (tmpvenlen < mintoklen);
84*0d6140beSAndroid Build Coastguard Worker 			maxvendorlen = max(maxvendorlen, tmpvenlen);
85*0d6140beSAndroid Build Coastguard Worker 			if (tmpven[0] == '\0')
86*0d6140beSAndroid Build Coastguard Worker 				break;
87*0d6140beSAndroid Build Coastguard Worker 		} while (1);
88*0d6140beSAndroid Build Coastguard Worker 
89*0d6140beSAndroid Build Coastguard Worker 		/* same for device name */
90*0d6140beSAndroid Build Coastguard Worker 		tmpdev = (char *)chip->name;
91*0d6140beSAndroid Build Coastguard Worker 		do {
92*0d6140beSAndroid Build Coastguard Worker 			tmpdevlen = 0;
93*0d6140beSAndroid Build Coastguard Worker 			do {
94*0d6140beSAndroid Build Coastguard Worker 				tmpdevlen += strcspn(tmpdev, delim);
95*0d6140beSAndroid Build Coastguard Worker 				tmpdev += tmpdevlen;
96*0d6140beSAndroid Build Coastguard Worker 				if (tmpdev[0] == '\0')
97*0d6140beSAndroid Build Coastguard Worker 					break;
98*0d6140beSAndroid Build Coastguard Worker 				tmpdev++;
99*0d6140beSAndroid Build Coastguard Worker 			} while (tmpdevlen < mintoklen);
100*0d6140beSAndroid Build Coastguard Worker 			maxchiplen = max(maxchiplen, tmpdevlen);
101*0d6140beSAndroid Build Coastguard Worker 			if (tmpdev[0] == '\0')
102*0d6140beSAndroid Build Coastguard Worker 				break;
103*0d6140beSAndroid Build Coastguard Worker 		} while (1);
104*0d6140beSAndroid Build Coastguard Worker 
105*0d6140beSAndroid Build Coastguard Worker 		s = flashbuses_to_text(chip->bustype);
106*0d6140beSAndroid Build Coastguard Worker 		if (s == NULL) {
107*0d6140beSAndroid Build Coastguard Worker 			msg_gerr("Out of memory!\n");
108*0d6140beSAndroid Build Coastguard Worker 			return 1;
109*0d6140beSAndroid Build Coastguard Worker 		}
110*0d6140beSAndroid Build Coastguard Worker 		maxtypelen = max(maxtypelen, strlen(s));
111*0d6140beSAndroid Build Coastguard Worker 		free(s);
112*0d6140beSAndroid Build Coastguard Worker 	}
113*0d6140beSAndroid Build Coastguard Worker 	maxvendorlen += border;
114*0d6140beSAndroid Build Coastguard Worker 	maxchiplen += border;
115*0d6140beSAndroid Build Coastguard Worker 	maxtypelen += border;
116*0d6140beSAndroid Build Coastguard Worker 
117*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("Supported flash chips (total: %d):\n\n", chipcount);
118*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("Vendor");
119*0d6140beSAndroid Build Coastguard Worker 	for (i = strlen("Vendor"); i < maxvendorlen; i++)
120*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
121*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("Device");
122*0d6140beSAndroid Build Coastguard Worker 	for (i = strlen("Device"); i < maxchiplen; i++)
123*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
124*0d6140beSAndroid Build Coastguard Worker 
125*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("Test ");
126*0d6140beSAndroid Build Coastguard Worker 	for (i = 0; i < border; i++)
127*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
128*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("Known");
129*0d6140beSAndroid Build Coastguard Worker 	for (i = 0; i < border; i++)
130*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
131*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo(" Size ");
132*0d6140beSAndroid Build Coastguard Worker 	for (i = 0; i < border; i++)
133*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
134*0d6140beSAndroid Build Coastguard Worker 
135*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("Type");
136*0d6140beSAndroid Build Coastguard Worker 	for (i = strlen("Type"); i < maxtypelen; i++)
137*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
138*0d6140beSAndroid Build Coastguard Worker 	msg_gdbg("Voltage");
139*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("\n");
140*0d6140beSAndroid Build Coastguard Worker 
141*0d6140beSAndroid Build Coastguard Worker 	for (i = 0; i < maxvendorlen + maxchiplen; i++)
142*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
143*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("OK   ");
144*0d6140beSAndroid Build Coastguard Worker 	for (i = 0; i < border; i++)
145*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
146*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("Broken");
147*0d6140beSAndroid Build Coastguard Worker 	for (i = 0; i < border; i++)
148*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
149*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("[kB] ");
150*0d6140beSAndroid Build Coastguard Worker 	for (i = 0; i < border + maxtypelen; i++)
151*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
152*0d6140beSAndroid Build Coastguard Worker 	msg_gdbg("range [V]");
153*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("\n\n");
154*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("(P = PROBE, R = READ, E = ERASE, W = WRITE, B = block-protect, - = N/A)\n\n");
155*0d6140beSAndroid Build Coastguard Worker 
156*0d6140beSAndroid Build Coastguard Worker 	for (chip = flashchips; chip->name != NULL; chip++) {
157*0d6140beSAndroid Build Coastguard Worker 		/* Don't print generic entries. */
158*0d6140beSAndroid Build Coastguard Worker 		if (!strncmp(chip->vendor, "Unknown", 7) ||
159*0d6140beSAndroid Build Coastguard Worker 		    !strncmp(chip->vendor, "Programmer", 10) ||
160*0d6140beSAndroid Build Coastguard Worker 		    !strncmp(chip->name, "unknown", 7))
161*0d6140beSAndroid Build Coastguard Worker 			continue;
162*0d6140beSAndroid Build Coastguard Worker 
163*0d6140beSAndroid Build Coastguard Worker 		/* support for multiline vendor names:
164*0d6140beSAndroid Build Coastguard Worker 		 * - make a copy of the original vendor name
165*0d6140beSAndroid Build Coastguard Worker 		 * - use strok to put the first token in tmpven
166*0d6140beSAndroid Build Coastguard Worker 		 * - keep track of the length of all tokens on the current line
167*0d6140beSAndroid Build Coastguard Worker 		 *   for ' '-padding in curvenlen
168*0d6140beSAndroid Build Coastguard Worker 		 * - check if additional tokens should be printed on the current
169*0d6140beSAndroid Build Coastguard Worker 		 *   line
170*0d6140beSAndroid Build Coastguard Worker 		 * - after all other values are printed print the surplus tokens
171*0d6140beSAndroid Build Coastguard Worker 		 *   on fresh lines
172*0d6140beSAndroid Build Coastguard Worker 		 */
173*0d6140beSAndroid Build Coastguard Worker 		ven = malloc(strlen(chip->vendor) + 1);
174*0d6140beSAndroid Build Coastguard Worker 		if (ven == NULL) {
175*0d6140beSAndroid Build Coastguard Worker 			msg_gerr("Out of memory!\n");
176*0d6140beSAndroid Build Coastguard Worker 			return 1;
177*0d6140beSAndroid Build Coastguard Worker 		}
178*0d6140beSAndroid Build Coastguard Worker 		strcpy(ven, chip->vendor);
179*0d6140beSAndroid Build Coastguard Worker 
180*0d6140beSAndroid Build Coastguard Worker 		tmpven = strtok_r(ven, delim, &tmpven_save);
181*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo("%s", tmpven);
182*0d6140beSAndroid Build Coastguard Worker 		curvenlen = strlen(tmpven);
183*0d6140beSAndroid Build Coastguard Worker 		while ((tmpven = strtok_r(NULL, delim, &tmpven_save)) != NULL) {
184*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("%s", delim);
185*0d6140beSAndroid Build Coastguard Worker 			curvenlen++;
186*0d6140beSAndroid Build Coastguard Worker 			tmpvenlen = strlen(tmpven);
187*0d6140beSAndroid Build Coastguard Worker 			if (tmpvenlen >= mintoklen)
188*0d6140beSAndroid Build Coastguard Worker 				break; /* big enough to be on its own line */
189*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("%s", tmpven);
190*0d6140beSAndroid Build Coastguard Worker 			curvenlen += tmpvenlen;
191*0d6140beSAndroid Build Coastguard Worker 		}
192*0d6140beSAndroid Build Coastguard Worker 
193*0d6140beSAndroid Build Coastguard Worker 		for (i = curvenlen; i < maxvendorlen; i++)
194*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
195*0d6140beSAndroid Build Coastguard Worker 
196*0d6140beSAndroid Build Coastguard Worker 		/* support for multiline device names as above */
197*0d6140beSAndroid Build Coastguard Worker 		dev = malloc(strlen(chip->name) + 1);
198*0d6140beSAndroid Build Coastguard Worker 		if (dev == NULL) {
199*0d6140beSAndroid Build Coastguard Worker 			msg_gerr("Out of memory!\n");
200*0d6140beSAndroid Build Coastguard Worker 			free(ven);
201*0d6140beSAndroid Build Coastguard Worker 			return 1;
202*0d6140beSAndroid Build Coastguard Worker 		}
203*0d6140beSAndroid Build Coastguard Worker 		strcpy(dev, chip->name);
204*0d6140beSAndroid Build Coastguard Worker 
205*0d6140beSAndroid Build Coastguard Worker 		tmpdev = strtok_r(dev, delim, &tmpdev_save);
206*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo("%s", tmpdev);
207*0d6140beSAndroid Build Coastguard Worker 		curdevlen = strlen(tmpdev);
208*0d6140beSAndroid Build Coastguard Worker 		while ((tmpdev = strtok_r(NULL, delim, &tmpdev_save)) != NULL) {
209*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("%s", delim);
210*0d6140beSAndroid Build Coastguard Worker 			curdevlen++;
211*0d6140beSAndroid Build Coastguard Worker 			tmpdevlen = strlen(tmpdev);
212*0d6140beSAndroid Build Coastguard Worker 			if (tmpdevlen >= mintoklen)
213*0d6140beSAndroid Build Coastguard Worker 				break; /* big enough to be on its own line */
214*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("%s", tmpdev);
215*0d6140beSAndroid Build Coastguard Worker 			curdevlen += tmpdevlen;
216*0d6140beSAndroid Build Coastguard Worker 		}
217*0d6140beSAndroid Build Coastguard Worker 
218*0d6140beSAndroid Build Coastguard Worker 		for (i = curdevlen; i < maxchiplen; i++)
219*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
220*0d6140beSAndroid Build Coastguard Worker 
221*0d6140beSAndroid Build Coastguard Worker 		if (chip->tested.probe == OK)
222*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("P");
223*0d6140beSAndroid Build Coastguard Worker 		else if (chip->tested.probe == NA)
224*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("-");
225*0d6140beSAndroid Build Coastguard Worker 		else
226*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
227*0d6140beSAndroid Build Coastguard Worker 		if (chip->tested.read == OK)
228*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("R");
229*0d6140beSAndroid Build Coastguard Worker 		else if (chip->tested.read == NA)
230*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("-");
231*0d6140beSAndroid Build Coastguard Worker 		else
232*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
233*0d6140beSAndroid Build Coastguard Worker 		if (chip->tested.erase == OK)
234*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("E");
235*0d6140beSAndroid Build Coastguard Worker 		else if (chip->tested.erase == NA)
236*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("-");
237*0d6140beSAndroid Build Coastguard Worker 		else
238*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
239*0d6140beSAndroid Build Coastguard Worker 		if (chip->tested.write == OK)
240*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("W");
241*0d6140beSAndroid Build Coastguard Worker 		else if (chip->tested.write == NA)
242*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("-");
243*0d6140beSAndroid Build Coastguard Worker 		else
244*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
245*0d6140beSAndroid Build Coastguard Worker 		if (chip->tested.wp == OK)
246*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("B");
247*0d6140beSAndroid Build Coastguard Worker 		else if (chip->tested.wp == NA)
248*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("-");
249*0d6140beSAndroid Build Coastguard Worker 		else
250*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
251*0d6140beSAndroid Build Coastguard Worker 		for (i = 0; i < border; i++)
252*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
253*0d6140beSAndroid Build Coastguard Worker 
254*0d6140beSAndroid Build Coastguard Worker 		if (chip->tested.probe == BAD)
255*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("P");
256*0d6140beSAndroid Build Coastguard Worker 		else
257*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
258*0d6140beSAndroid Build Coastguard Worker 		if (chip->tested.read == BAD)
259*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("R");
260*0d6140beSAndroid Build Coastguard Worker 		else
261*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
262*0d6140beSAndroid Build Coastguard Worker 		if (chip->tested.erase == BAD)
263*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("E");
264*0d6140beSAndroid Build Coastguard Worker 		else
265*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
266*0d6140beSAndroid Build Coastguard Worker 		if (chip->tested.write == BAD)
267*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("W");
268*0d6140beSAndroid Build Coastguard Worker 		else
269*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
270*0d6140beSAndroid Build Coastguard Worker 		if (chip->tested.wp == BAD)
271*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("B");
272*0d6140beSAndroid Build Coastguard Worker 		else
273*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
274*0d6140beSAndroid Build Coastguard Worker 		for (i = 0; i < border + 1; i++)
275*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
276*0d6140beSAndroid Build Coastguard Worker 
277*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo("%6d", chip->total_size);
278*0d6140beSAndroid Build Coastguard Worker 		for (i = 0; i < border; i++)
279*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
280*0d6140beSAndroid Build Coastguard Worker 
281*0d6140beSAndroid Build Coastguard Worker 		s = flashbuses_to_text(chip->bustype);
282*0d6140beSAndroid Build Coastguard Worker 		if (s == NULL) {
283*0d6140beSAndroid Build Coastguard Worker 			msg_gerr("Out of memory!\n");
284*0d6140beSAndroid Build Coastguard Worker 			free(ven);
285*0d6140beSAndroid Build Coastguard Worker 			free(dev);
286*0d6140beSAndroid Build Coastguard Worker 			return 1;
287*0d6140beSAndroid Build Coastguard Worker 		}
288*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo("%s", s);
289*0d6140beSAndroid Build Coastguard Worker 		for (i = strlen(s); i < maxtypelen; i++)
290*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
291*0d6140beSAndroid Build Coastguard Worker 		free(s);
292*0d6140beSAndroid Build Coastguard Worker 
293*0d6140beSAndroid Build Coastguard Worker 		if (chip->voltage.min == 0 && chip->voltage.max == 0)
294*0d6140beSAndroid Build Coastguard Worker 			msg_gdbg("no info");
295*0d6140beSAndroid Build Coastguard Worker 		else
296*0d6140beSAndroid Build Coastguard Worker 			msg_gdbg("%0.02f;%0.02f",
297*0d6140beSAndroid Build Coastguard Worker 				 chip->voltage.min/(double)1000,
298*0d6140beSAndroid Build Coastguard Worker 				 chip->voltage.max/(double)1000);
299*0d6140beSAndroid Build Coastguard Worker 
300*0d6140beSAndroid Build Coastguard Worker 		/* print surplus vendor and device name tokens */
301*0d6140beSAndroid Build Coastguard Worker 		while (tmpven != NULL || tmpdev != NULL) {
302*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo("\n");
303*0d6140beSAndroid Build Coastguard Worker 			if (tmpven != NULL){
304*0d6140beSAndroid Build Coastguard Worker 				msg_ginfo("%s", tmpven);
305*0d6140beSAndroid Build Coastguard Worker 				curvenlen = strlen(tmpven);
306*0d6140beSAndroid Build Coastguard Worker 				while ((tmpven = strtok_r(NULL, delim, &tmpven_save)) != NULL) {
307*0d6140beSAndroid Build Coastguard Worker 					msg_ginfo("%s", delim);
308*0d6140beSAndroid Build Coastguard Worker 					curvenlen++;
309*0d6140beSAndroid Build Coastguard Worker 					tmpvenlen = strlen(tmpven);
310*0d6140beSAndroid Build Coastguard Worker 					/* big enough to be on its own line */
311*0d6140beSAndroid Build Coastguard Worker 					if (tmpvenlen >= mintoklen)
312*0d6140beSAndroid Build Coastguard Worker 						break;
313*0d6140beSAndroid Build Coastguard Worker 					msg_ginfo("%s", tmpven);
314*0d6140beSAndroid Build Coastguard Worker 					curvenlen += tmpvenlen;
315*0d6140beSAndroid Build Coastguard Worker 				}
316*0d6140beSAndroid Build Coastguard Worker 			} else
317*0d6140beSAndroid Build Coastguard Worker 				curvenlen = 0;
318*0d6140beSAndroid Build Coastguard Worker 
319*0d6140beSAndroid Build Coastguard Worker 			for (i = curvenlen; i < maxvendorlen; i++)
320*0d6140beSAndroid Build Coastguard Worker 				msg_ginfo(" ");
321*0d6140beSAndroid Build Coastguard Worker 
322*0d6140beSAndroid Build Coastguard Worker 			if (tmpdev != NULL){
323*0d6140beSAndroid Build Coastguard Worker 				msg_ginfo("%s", tmpdev);
324*0d6140beSAndroid Build Coastguard Worker 				curdevlen = strlen(tmpdev);
325*0d6140beSAndroid Build Coastguard Worker 				while ((tmpdev = strtok_r(NULL, delim, &tmpdev_save)) != NULL) {
326*0d6140beSAndroid Build Coastguard Worker 					msg_ginfo("%s", delim);
327*0d6140beSAndroid Build Coastguard Worker 					curdevlen++;
328*0d6140beSAndroid Build Coastguard Worker 					tmpdevlen = strlen(tmpdev);
329*0d6140beSAndroid Build Coastguard Worker 					/* big enough to be on its own line */
330*0d6140beSAndroid Build Coastguard Worker 					if (tmpdevlen >= mintoklen)
331*0d6140beSAndroid Build Coastguard Worker 						break;
332*0d6140beSAndroid Build Coastguard Worker 					msg_ginfo("%s", tmpdev);
333*0d6140beSAndroid Build Coastguard Worker 					curdevlen += tmpdevlen;
334*0d6140beSAndroid Build Coastguard Worker 				}
335*0d6140beSAndroid Build Coastguard Worker 			}
336*0d6140beSAndroid Build Coastguard Worker 		}
337*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo("\n");
338*0d6140beSAndroid Build Coastguard Worker 		free(ven);
339*0d6140beSAndroid Build Coastguard Worker 		free(dev);
340*0d6140beSAndroid Build Coastguard Worker 	}
341*0d6140beSAndroid Build Coastguard Worker 
342*0d6140beSAndroid Build Coastguard Worker 	return 0;
343*0d6140beSAndroid Build Coastguard Worker }
344*0d6140beSAndroid Build Coastguard Worker 
345*0d6140beSAndroid Build Coastguard Worker #if CONFIG_INTERNAL == 1
print_supported_chipsets(void)346*0d6140beSAndroid Build Coastguard Worker static void print_supported_chipsets(void)
347*0d6140beSAndroid Build Coastguard Worker {
348*0d6140beSAndroid Build Coastguard Worker 	unsigned int i, chipsetcount = 0;
349*0d6140beSAndroid Build Coastguard Worker 	const struct penable *c = chipset_enables;
350*0d6140beSAndroid Build Coastguard Worker 	size_t maxvendorlen = strlen("Vendor") + 1;
351*0d6140beSAndroid Build Coastguard Worker 	size_t maxchipsetlen = strlen("Chipset") + 1;
352*0d6140beSAndroid Build Coastguard Worker 
353*0d6140beSAndroid Build Coastguard Worker 	for (c = chipset_enables; c->vendor_name != NULL; c++) {
354*0d6140beSAndroid Build Coastguard Worker 		chipsetcount++;
355*0d6140beSAndroid Build Coastguard Worker 		maxvendorlen = MAX(maxvendorlen, strlen(c->vendor_name));
356*0d6140beSAndroid Build Coastguard Worker 		maxchipsetlen = MAX(maxchipsetlen, strlen(c->device_name));
357*0d6140beSAndroid Build Coastguard Worker 	}
358*0d6140beSAndroid Build Coastguard Worker 	maxvendorlen++;
359*0d6140beSAndroid Build Coastguard Worker 	maxchipsetlen++;
360*0d6140beSAndroid Build Coastguard Worker 
361*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("Supported chipsets (total: %u):\n\n", chipsetcount);
362*0d6140beSAndroid Build Coastguard Worker 
363*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("Vendor");
364*0d6140beSAndroid Build Coastguard Worker 	for (i = strlen("Vendor"); i < maxvendorlen; i++)
365*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
366*0d6140beSAndroid Build Coastguard Worker 
367*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("Chipset");
368*0d6140beSAndroid Build Coastguard Worker 	for (i = strlen("Chipset"); i < maxchipsetlen; i++)
369*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
370*0d6140beSAndroid Build Coastguard Worker 
371*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("PCI IDs    Status\n\n");
372*0d6140beSAndroid Build Coastguard Worker 
373*0d6140beSAndroid Build Coastguard Worker 	for (c = chipset_enables; c->vendor_name != NULL; c++) {
374*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo("%s", c->vendor_name);
375*0d6140beSAndroid Build Coastguard Worker 		for (i = 0; i < maxvendorlen - strlen(c->vendor_name); i++)
376*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
377*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo("%s", c->device_name);
378*0d6140beSAndroid Build Coastguard Worker 		for (i = 0; i < maxchipsetlen - strlen(c->device_name); i++)
379*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
380*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo("%04x:%04x  %s\n", c->vendor_id, c->device_id,
381*0d6140beSAndroid Build Coastguard Worker 		       test_state_to_text(c->status));
382*0d6140beSAndroid Build Coastguard Worker 	}
383*0d6140beSAndroid Build Coastguard Worker }
384*0d6140beSAndroid Build Coastguard Worker 
print_supported_boards_helper(const struct board_info * boards,const char * devicetype)385*0d6140beSAndroid Build Coastguard Worker static void print_supported_boards_helper(const struct board_info *boards,
386*0d6140beSAndroid Build Coastguard Worker 				   const char *devicetype)
387*0d6140beSAndroid Build Coastguard Worker {
388*0d6140beSAndroid Build Coastguard Worker 	unsigned int i;
389*0d6140beSAndroid Build Coastguard Worker 	unsigned int boardcount_good = 0, boardcount_bad = 0, boardcount_nt = 0;
390*0d6140beSAndroid Build Coastguard Worker 	const struct board_match *e = board_matches;
391*0d6140beSAndroid Build Coastguard Worker 	const struct board_info *b = boards;
392*0d6140beSAndroid Build Coastguard Worker 	size_t maxvendorlen = strlen("Vendor") + 1;
393*0d6140beSAndroid Build Coastguard Worker 	size_t maxboardlen = strlen("Board") + 1;
394*0d6140beSAndroid Build Coastguard Worker 
395*0d6140beSAndroid Build Coastguard Worker 	for (b = boards; b->vendor != NULL; b++) {
396*0d6140beSAndroid Build Coastguard Worker 		maxvendorlen = max(maxvendorlen, strlen(b->vendor));
397*0d6140beSAndroid Build Coastguard Worker 		maxboardlen = max(maxboardlen, strlen(b->name));
398*0d6140beSAndroid Build Coastguard Worker 		if (b->working == OK)
399*0d6140beSAndroid Build Coastguard Worker 			boardcount_good++;
400*0d6140beSAndroid Build Coastguard Worker 		else if (b->working == NT)
401*0d6140beSAndroid Build Coastguard Worker 			boardcount_nt++;
402*0d6140beSAndroid Build Coastguard Worker 		else
403*0d6140beSAndroid Build Coastguard Worker 			boardcount_bad++;
404*0d6140beSAndroid Build Coastguard Worker 	}
405*0d6140beSAndroid Build Coastguard Worker 	maxvendorlen++;
406*0d6140beSAndroid Build Coastguard Worker 	maxboardlen++;
407*0d6140beSAndroid Build Coastguard Worker 
408*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("%d known %s (good: %d, untested: %d, bad: %d):\n\n",
409*0d6140beSAndroid Build Coastguard Worker 		  boardcount_good + boardcount_nt + boardcount_bad,
410*0d6140beSAndroid Build Coastguard Worker 		  devicetype, boardcount_good, boardcount_nt, boardcount_bad);
411*0d6140beSAndroid Build Coastguard Worker 
412*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("Vendor");
413*0d6140beSAndroid Build Coastguard Worker 	for (i = strlen("Vendor"); i < maxvendorlen; i++)
414*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
415*0d6140beSAndroid Build Coastguard Worker 
416*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("Board");
417*0d6140beSAndroid Build Coastguard Worker 	for (i = strlen("Board"); i < maxboardlen; i++)
418*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
419*0d6140beSAndroid Build Coastguard Worker 
420*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("Status  Required value for\n");
421*0d6140beSAndroid Build Coastguard Worker 	for (i = 0; i < maxvendorlen + maxboardlen + strlen("Status  "); i++)
422*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
423*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("-p internal:mainboard=\n");
424*0d6140beSAndroid Build Coastguard Worker 
425*0d6140beSAndroid Build Coastguard Worker 	for (b = boards; b->vendor != NULL; b++) {
426*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo("%s", b->vendor);
427*0d6140beSAndroid Build Coastguard Worker 		for (i = 0; i < maxvendorlen - strlen(b->vendor); i++)
428*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
429*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo("%s", b->name);
430*0d6140beSAndroid Build Coastguard Worker 		for (i = 0; i < maxboardlen - strlen(b->name); i++)
431*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
432*0d6140beSAndroid Build Coastguard Worker 
433*0d6140beSAndroid Build Coastguard Worker 		switch (b->working) {
434*0d6140beSAndroid Build Coastguard Worker 		case OK:  msg_ginfo("OK      "); break;
435*0d6140beSAndroid Build Coastguard Worker 		case NT:  msg_ginfo("NT      "); break;
436*0d6140beSAndroid Build Coastguard Worker 		case DEP: msg_ginfo("DEP     "); break;
437*0d6140beSAndroid Build Coastguard Worker 		case NA:  msg_ginfo("N/A     "); break;
438*0d6140beSAndroid Build Coastguard Worker 		case BAD:
439*0d6140beSAndroid Build Coastguard Worker 		default:  msg_ginfo("BAD     "); break;
440*0d6140beSAndroid Build Coastguard Worker 		}
441*0d6140beSAndroid Build Coastguard Worker 
442*0d6140beSAndroid Build Coastguard Worker 		for (e = board_matches; e->vendor_name != NULL; e++) {
443*0d6140beSAndroid Build Coastguard Worker 			if (strcmp(e->vendor_name, b->vendor)
444*0d6140beSAndroid Build Coastguard Worker 			    || strcmp(e->board_name, b->name))
445*0d6140beSAndroid Build Coastguard Worker 				continue;
446*0d6140beSAndroid Build Coastguard Worker 			if (e->lb_vendor == NULL)
447*0d6140beSAndroid Build Coastguard Worker 				msg_ginfo("(autodetected)");
448*0d6140beSAndroid Build Coastguard Worker 			else
449*0d6140beSAndroid Build Coastguard Worker 				msg_ginfo("%s:%s", e->lb_vendor,
450*0d6140beSAndroid Build Coastguard Worker 						   e->lb_part);
451*0d6140beSAndroid Build Coastguard Worker 		}
452*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo("\n");
453*0d6140beSAndroid Build Coastguard Worker 	}
454*0d6140beSAndroid Build Coastguard Worker }
455*0d6140beSAndroid Build Coastguard Worker #endif
456*0d6140beSAndroid Build Coastguard Worker 
print_supported_devs(const struct programmer_entry * const prog,const char * const type,int * num_devs)457*0d6140beSAndroid Build Coastguard Worker static void print_supported_devs(const struct programmer_entry *const prog, const char *const type,
458*0d6140beSAndroid Build Coastguard Worker 				int* num_devs)
459*0d6140beSAndroid Build Coastguard Worker {
460*0d6140beSAndroid Build Coastguard Worker 	const struct dev_entry *const devs = prog->devs.dev;
461*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("\nSupported %s devices for the %s programmer:\n", type, prog->name);
462*0d6140beSAndroid Build Coastguard Worker 	unsigned int maxvendorlen = strlen("Vendor") + 1;
463*0d6140beSAndroid Build Coastguard Worker 	unsigned int maxdevlen = strlen("Device") + 1;
464*0d6140beSAndroid Build Coastguard Worker 
465*0d6140beSAndroid Build Coastguard Worker 	unsigned int i;
466*0d6140beSAndroid Build Coastguard Worker 	for (i = 0; devs[i].vendor_name != NULL; i++) {
467*0d6140beSAndroid Build Coastguard Worker 		maxvendorlen = max(maxvendorlen, strlen(devs[i].vendor_name));
468*0d6140beSAndroid Build Coastguard Worker 		maxdevlen = max(maxdevlen, strlen(devs[i].device_name));
469*0d6140beSAndroid Build Coastguard Worker 	}
470*0d6140beSAndroid Build Coastguard Worker 	maxvendorlen++;
471*0d6140beSAndroid Build Coastguard Worker 	maxdevlen++;
472*0d6140beSAndroid Build Coastguard Worker 
473*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("Vendor");
474*0d6140beSAndroid Build Coastguard Worker 	for (i = strlen("Vendor"); i < maxvendorlen; i++)
475*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
476*0d6140beSAndroid Build Coastguard Worker 
477*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("Device");
478*0d6140beSAndroid Build Coastguard Worker 	for (i = strlen("Device"); i < maxdevlen; i++)
479*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" ");
480*0d6140beSAndroid Build Coastguard Worker 
481*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo(" %s IDs    Status\n", type);
482*0d6140beSAndroid Build Coastguard Worker 
483*0d6140beSAndroid Build Coastguard Worker 	for (i = 0; devs[i].vendor_name != NULL; i++) {
484*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo("%s", devs[i].vendor_name);
485*0d6140beSAndroid Build Coastguard Worker 		unsigned int j;
486*0d6140beSAndroid Build Coastguard Worker 		for (j = strlen(devs[i].vendor_name); j < maxvendorlen; j++)
487*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
488*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo("%s", devs[i].device_name);
489*0d6140beSAndroid Build Coastguard Worker 		for (j = strlen(devs[i].device_name); j < maxdevlen; j++)
490*0d6140beSAndroid Build Coastguard Worker 			msg_ginfo(" ");
491*0d6140beSAndroid Build Coastguard Worker 
492*0d6140beSAndroid Build Coastguard Worker 		msg_pinfo(" %04x:%04x  %s\n", devs[i].vendor_id, devs[i].device_id,
493*0d6140beSAndroid Build Coastguard Worker 			  test_state_to_text(devs[i].status));
494*0d6140beSAndroid Build Coastguard Worker 		if (devs[i].status == OK || devs[i].status == NT || devs[i].status == DEP)
495*0d6140beSAndroid Build Coastguard Worker 			*num_devs += 1;
496*0d6140beSAndroid Build Coastguard Worker 	}
497*0d6140beSAndroid Build Coastguard Worker }
498*0d6140beSAndroid Build Coastguard Worker 
print_supported(void)499*0d6140beSAndroid Build Coastguard Worker int print_supported(void)
500*0d6140beSAndroid Build Coastguard Worker {
501*0d6140beSAndroid Build Coastguard Worker 	unsigned int i;
502*0d6140beSAndroid Build Coastguard Worker 	int num_pci_devs = 0;
503*0d6140beSAndroid Build Coastguard Worker 	int num_usb_devs = 0;
504*0d6140beSAndroid Build Coastguard Worker 
505*0d6140beSAndroid Build Coastguard Worker 	if (print_supported_chips())
506*0d6140beSAndroid Build Coastguard Worker 		return 1;
507*0d6140beSAndroid Build Coastguard Worker 
508*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("\nSupported programmers:\n");
509*0d6140beSAndroid Build Coastguard Worker 	list_programmers_linebreak(0, 80, 0);
510*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("\n");
511*0d6140beSAndroid Build Coastguard Worker #if CONFIG_INTERNAL == 1
512*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("\nSupported devices for the internal programmer:\n\n");
513*0d6140beSAndroid Build Coastguard Worker 	print_supported_chipsets();
514*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("\n");
515*0d6140beSAndroid Build Coastguard Worker 	print_supported_boards_helper(boards_known, "mainboards");
516*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("\n");
517*0d6140beSAndroid Build Coastguard Worker 	print_supported_boards_helper(laptops_known, "mobile devices");
518*0d6140beSAndroid Build Coastguard Worker #endif
519*0d6140beSAndroid Build Coastguard Worker 	for (i = 0; i < programmer_table_size; i++) {
520*0d6140beSAndroid Build Coastguard Worker 		const struct programmer_entry *const prog = programmer_table[i];
521*0d6140beSAndroid Build Coastguard Worker 		switch (prog->type) {
522*0d6140beSAndroid Build Coastguard Worker 		case USB:
523*0d6140beSAndroid Build Coastguard Worker 			print_supported_devs(prog, "USB", &num_usb_devs);
524*0d6140beSAndroid Build Coastguard Worker 			break;
525*0d6140beSAndroid Build Coastguard Worker 		case PCI:
526*0d6140beSAndroid Build Coastguard Worker 			print_supported_devs(prog, "PCI", &num_pci_devs);
527*0d6140beSAndroid Build Coastguard Worker 			break;
528*0d6140beSAndroid Build Coastguard Worker 		case OTHER:
529*0d6140beSAndroid Build Coastguard Worker 			if (prog->devs.note != NULL) {
530*0d6140beSAndroid Build Coastguard Worker 				msg_ginfo("\nSupported devices for the %s programmer:\n", prog->name);
531*0d6140beSAndroid Build Coastguard Worker 				msg_ginfo("%s", prog->devs.note);
532*0d6140beSAndroid Build Coastguard Worker 			}
533*0d6140beSAndroid Build Coastguard Worker 			break;
534*0d6140beSAndroid Build Coastguard Worker 		default:
535*0d6140beSAndroid Build Coastguard Worker 			msg_gerr("\n%s: %s: Uninitialized programmer type! Please report a bug at "
536*0d6140beSAndroid Build Coastguard Worker 				 "[email protected]\n", __func__, prog->name);
537*0d6140beSAndroid Build Coastguard Worker 			break;
538*0d6140beSAndroid Build Coastguard Worker 		}
539*0d6140beSAndroid Build Coastguard Worker 	}
540*0d6140beSAndroid Build Coastguard Worker 
541*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("\nSupported USB devices, total %d\nSupported PCI devices, total %d\n",
542*0d6140beSAndroid Build Coastguard Worker 			num_usb_devs, num_pci_devs);
543*0d6140beSAndroid Build Coastguard Worker 
544*0d6140beSAndroid Build Coastguard Worker 	return 0;
545*0d6140beSAndroid Build Coastguard Worker }
546*0d6140beSAndroid Build Coastguard Worker 
print_sysinfo(void)547*0d6140beSAndroid Build Coastguard Worker static void print_sysinfo(void)
548*0d6140beSAndroid Build Coastguard Worker {
549*0d6140beSAndroid Build Coastguard Worker #if IS_WINDOWS
550*0d6140beSAndroid Build Coastguard Worker 	SYSTEM_INFO si = { 0 };
551*0d6140beSAndroid Build Coastguard Worker 	OSVERSIONINFOEX osvi = { 0 };
552*0d6140beSAndroid Build Coastguard Worker 
553*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo(" on Windows");
554*0d6140beSAndroid Build Coastguard Worker 	/* Tell Windows which version of the structure we want. */
555*0d6140beSAndroid Build Coastguard Worker 	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
556*0d6140beSAndroid Build Coastguard Worker 	if (GetVersionEx((OSVERSIONINFO*) &osvi))
557*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" %lu.%lu", (unsigned long)osvi.dwMajorVersion,
558*0d6140beSAndroid Build Coastguard Worker 			(unsigned long)osvi.dwMinorVersion);
559*0d6140beSAndroid Build Coastguard Worker 	else
560*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" unknown version");
561*0d6140beSAndroid Build Coastguard Worker 	GetSystemInfo(&si);
562*0d6140beSAndroid Build Coastguard Worker 	switch (si.wProcessorArchitecture) {
563*0d6140beSAndroid Build Coastguard Worker 	case PROCESSOR_ARCHITECTURE_AMD64:
564*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" (x86_64)");
565*0d6140beSAndroid Build Coastguard Worker 		break;
566*0d6140beSAndroid Build Coastguard Worker 	case PROCESSOR_ARCHITECTURE_INTEL:
567*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" (x86)");
568*0d6140beSAndroid Build Coastguard Worker 		break;
569*0d6140beSAndroid Build Coastguard Worker 	default:
570*0d6140beSAndroid Build Coastguard Worker 		msg_ginfo(" (unknown arch)");
571*0d6140beSAndroid Build Coastguard Worker 		break;
572*0d6140beSAndroid Build Coastguard Worker 	}
573*0d6140beSAndroid Build Coastguard Worker #elif HAVE_UTSNAME == 1
574*0d6140beSAndroid Build Coastguard Worker 	struct utsname osinfo;
575*0d6140beSAndroid Build Coastguard Worker 
576*0d6140beSAndroid Build Coastguard Worker 	uname(&osinfo);
577*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
578*0d6140beSAndroid Build Coastguard Worker 		  osinfo.machine);
579*0d6140beSAndroid Build Coastguard Worker #else
580*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo(" on unknown machine");
581*0d6140beSAndroid Build Coastguard Worker #endif
582*0d6140beSAndroid Build Coastguard Worker }
583*0d6140beSAndroid Build Coastguard Worker 
print_buildinfo(void)584*0d6140beSAndroid Build Coastguard Worker void print_buildinfo(void)
585*0d6140beSAndroid Build Coastguard Worker {
586*0d6140beSAndroid Build Coastguard Worker 	msg_gdbg("flashrom was built with");
587*0d6140beSAndroid Build Coastguard Worker #ifdef __clang__
588*0d6140beSAndroid Build Coastguard Worker 	msg_gdbg(" LLVM Clang");
589*0d6140beSAndroid Build Coastguard Worker #ifdef __clang_version__
590*0d6140beSAndroid Build Coastguard Worker 	msg_gdbg(" %s,", __clang_version__);
591*0d6140beSAndroid Build Coastguard Worker #else
592*0d6140beSAndroid Build Coastguard Worker 	msg_gdbg(" unknown version (before r102686),");
593*0d6140beSAndroid Build Coastguard Worker #endif
594*0d6140beSAndroid Build Coastguard Worker #elif defined(__GNUC__)
595*0d6140beSAndroid Build Coastguard Worker 	msg_gdbg(" GCC");
596*0d6140beSAndroid Build Coastguard Worker #ifdef __VERSION__
597*0d6140beSAndroid Build Coastguard Worker 	msg_gdbg(" %s,", __VERSION__);
598*0d6140beSAndroid Build Coastguard Worker #else
599*0d6140beSAndroid Build Coastguard Worker 	msg_gdbg(" unknown version,");
600*0d6140beSAndroid Build Coastguard Worker #endif
601*0d6140beSAndroid Build Coastguard Worker #else
602*0d6140beSAndroid Build Coastguard Worker 	msg_gdbg(" unknown compiler,");
603*0d6140beSAndroid Build Coastguard Worker #endif
604*0d6140beSAndroid Build Coastguard Worker #if defined (__FLASHROM_LITTLE_ENDIAN__)
605*0d6140beSAndroid Build Coastguard Worker 	msg_gdbg(" little endian");
606*0d6140beSAndroid Build Coastguard Worker #elif defined (__FLASHROM_BIG_ENDIAN__)
607*0d6140beSAndroid Build Coastguard Worker 	msg_gdbg(" big endian");
608*0d6140beSAndroid Build Coastguard Worker #else
609*0d6140beSAndroid Build Coastguard Worker #error Endianness could not be determined
610*0d6140beSAndroid Build Coastguard Worker #endif
611*0d6140beSAndroid Build Coastguard Worker 	msg_gdbg("\n");
612*0d6140beSAndroid Build Coastguard Worker }
613*0d6140beSAndroid Build Coastguard Worker 
print_version(void)614*0d6140beSAndroid Build Coastguard Worker void print_version(void)
615*0d6140beSAndroid Build Coastguard Worker {
616*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("flashrom %s", flashrom_version_info());
617*0d6140beSAndroid Build Coastguard Worker 	print_sysinfo();
618*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("\n");
619*0d6140beSAndroid Build Coastguard Worker }
620*0d6140beSAndroid Build Coastguard Worker 
print_banner(void)621*0d6140beSAndroid Build Coastguard Worker void print_banner(void)
622*0d6140beSAndroid Build Coastguard Worker {
623*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("flashrom is free software, get the source code at "
624*0d6140beSAndroid Build Coastguard Worker 		  "https://flashrom.org\n");
625*0d6140beSAndroid Build Coastguard Worker 	msg_ginfo("\n");
626*0d6140beSAndroid Build Coastguard Worker }
627