blob: d4cafb88f4831bfc347a240d3b1de4576915de7a [file] [log] [blame]
Uwe Hermannba290d12009-06-17 12:07:12 +00001/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
5 * Copyright (C) 2009 Carl-Daniel Hailfinger
Stefan Tauner4a038652013-07-17 09:28:00 +00006 * Copyright (C) 2011-2013 Stefan Tauner
Uwe Hermannba290d12009-06-17 12:07:12 +00007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
Uwe Hermannba290d12009-06-17 12:07:12 +000017 */
18
Carl-Daniel Hailfinger831e8f42010-05-30 22:24:40 +000019#include <stdio.h>
Uwe Hermannba290d12009-06-17 12:07:12 +000020#include <string.h>
21#include <stdlib.h>
Nico Huber519be662018-12-23 20:03:35 +010022#include <stddef.h>
Edward O'Callaghan3b64d812022-08-12 13:07:51 +100023#if HAVE_UTSNAME == 1
24#include <sys/utsname.h>
25#endif
26#if IS_WINDOWS
27#include <windows.h>
28#undef min
29#undef max
30#endif
31
Uwe Hermannba290d12009-06-17 12:07:12 +000032#include "flash.h"
Carl-Daniel Hailfinger5b997c32010-07-27 22:41:39 +000033#include "programmer.h"
Uwe Hermannba290d12009-06-17 12:07:12 +000034
Edward O'Callaghan3b64d812022-08-12 13:07:51 +100035static void print_sysinfo(void)
36{
37#if IS_WINDOWS
38 SYSTEM_INFO si = { 0 };
39 OSVERSIONINFOEX osvi = { 0 };
40
41 msg_ginfo(" on Windows");
42 /* Tell Windows which version of the structure we want. */
43 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
44 if (GetVersionEx((OSVERSIONINFO*) &osvi))
45 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
46 else
47 msg_ginfo(" unknown version");
48 GetSystemInfo(&si);
49 switch (si.wProcessorArchitecture) {
50 case PROCESSOR_ARCHITECTURE_AMD64:
51 msg_ginfo(" (x86_64)");
52 break;
53 case PROCESSOR_ARCHITECTURE_INTEL:
54 msg_ginfo(" (x86)");
55 break;
56 default:
57 msg_ginfo(" (unknown arch)");
58 break;
59 }
60#elif HAVE_UTSNAME == 1
61 struct utsname osinfo;
62
63 uname(&osinfo);
64 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
65 osinfo.machine);
66#else
67 msg_ginfo(" on unknown machine");
68#endif
69}
70
71void print_buildinfo(void)
72{
73 msg_gdbg("flashrom was built with");
74#ifdef __clang__
75 msg_gdbg(" LLVM Clang");
76#ifdef __clang_version__
77 msg_gdbg(" %s,", __clang_version__);
78#else
79 msg_gdbg(" unknown version (before r102686),");
80#endif
81#elif defined(__GNUC__)
82 msg_gdbg(" GCC");
83#ifdef __VERSION__
84 msg_gdbg(" %s,", __VERSION__);
85#else
86 msg_gdbg(" unknown version,");
87#endif
88#else
89 msg_gdbg(" unknown compiler,");
90#endif
91#if defined (__FLASHROM_LITTLE_ENDIAN__)
92 msg_gdbg(" little endian");
93#elif defined (__FLASHROM_BIG_ENDIAN__)
94 msg_gdbg(" big endian");
95#else
96#error Endianness could not be determined
97#endif
98 msg_gdbg("\n");
99}
100
101void print_version(void)
102{
103 msg_ginfo("flashrom-stable %s", flashrom_version);
104 print_sysinfo();
105 msg_ginfo("\n");
106}
107
108void print_banner(void)
109{
110 msg_ginfo("flashrom is free software, get the source code at "
111 "https://flashrom.org\n");
112 msg_ginfo("\n");
113}
114
Stefan Tauner1181ee22014-06-01 02:13:23 +0000115static const char *test_state_to_text(enum test_state test_state)
116{
117 switch (test_state) {
118 case OK: return "OK";
119 case BAD: return "Not working";
120 case NA: return "N/A";
121 case DEP: return "Config-dependent";
122 case NT:
123 default: return "Untested";
124 }
125}
126
Niklas Söderlundede2fa42012-10-23 13:06:46 +0000127static int print_supported_chips(void)
Uwe Hermannba290d12009-06-17 12:07:12 +0000128{
Stefan Tauner29e5d312011-09-12 22:55:01 +0000129 const char *delim = "/";
130 const int mintoklen = 5;
131 const int border = 2;
132 int i, chipcount = 0;
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000133 int maxvendorlen = strlen("Vendor") + 1;
134 int maxchiplen = strlen("Device") + 1;
Stefan Tauner29e5d312011-09-12 22:55:01 +0000135 int maxtypelen = strlen("Type") + 1;
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000136 const struct flashchip *chip;
Stefan Tauner00155492011-06-26 20:45:35 +0000137 char *s;
Stefan Tauner4a038652013-07-17 09:28:00 +0000138 char *ven, *dev;
139 char *tmpven, *tmpdev, *tmpven_save, *tmpdev_save;
Stefan Tauner29e5d312011-09-12 22:55:01 +0000140 int tmpvenlen, tmpdevlen, curvenlen, curdevlen;
Uwe Hermannba290d12009-06-17 12:07:12 +0000141
Stefan Tauner29e5d312011-09-12 22:55:01 +0000142 /* calculate maximum column widths and by iterating over all chips */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000143 for (chip = flashchips; chip->name != NULL; chip++) {
Stefan Tauner035492a2012-02-03 22:32:09 +0000144 /* Ignore generic entries. */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000145 if (!strncmp(chip->vendor, "Unknown", 7) ||
146 !strncmp(chip->vendor, "Programmer", 10) ||
147 !strncmp(chip->name, "unknown", 7))
Uwe Hermannba290d12009-06-17 12:07:12 +0000148 continue;
Uwe Hermannba290d12009-06-17 12:07:12 +0000149 chipcount++;
Stefan Tauner29e5d312011-09-12 22:55:01 +0000150
151 /* Find maximum vendor length (respecting line splitting). */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000152 tmpven = (char *)chip->vendor;
Stefan Tauner29e5d312011-09-12 22:55:01 +0000153 do {
154 /* and take minimum token lengths into account */
155 tmpvenlen = 0;
156 do {
157 tmpvenlen += strcspn(tmpven, delim);
158 /* skip to the address after the first token */
159 tmpven += tmpvenlen;
160 if (tmpven[0] == '\0')
161 break;
162 tmpven++;
163 } while (tmpvenlen < mintoklen);
164 maxvendorlen = max(maxvendorlen, tmpvenlen);
165 if (tmpven[0] == '\0')
166 break;
167 } while (1);
168
169 /* same for device name */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000170 tmpdev = (char *)chip->name;
Stefan Tauner29e5d312011-09-12 22:55:01 +0000171 do {
172 tmpdevlen = 0;
173 do {
174 tmpdevlen += strcspn(tmpdev, delim);
175 tmpdev += tmpdevlen;
176 if (tmpdev[0] == '\0')
177 break;
178 tmpdev++;
179 } while (tmpdevlen < mintoklen);
180 maxchiplen = max(maxchiplen, tmpdevlen);
181 if (tmpdev[0] == '\0')
182 break;
183 } while (1);
184
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000185 s = flashbuses_to_text(chip->bustype);
Stefan Tauner29e5d312011-09-12 22:55:01 +0000186 maxtypelen = max(maxtypelen, strlen(s));
187 free(s);
Carl-Daniel Hailfingerf7533422010-07-17 23:21:12 +0000188 }
Stefan Tauner29e5d312011-09-12 22:55:01 +0000189 maxvendorlen += border;
190 maxchiplen += border;
191 maxtypelen += border;
Uwe Hermannba290d12009-06-17 12:07:12 +0000192
Stefan Tauner12589362011-06-25 17:36:25 +0000193 msg_ginfo("Supported flash chips (total: %d):\n\n", chipcount);
194 msg_ginfo("Vendor");
Carl-Daniel Hailfingerf7533422010-07-17 23:21:12 +0000195 for (i = strlen("Vendor"); i < maxvendorlen; i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000196 msg_ginfo(" ");
197 msg_ginfo("Device");
Carl-Daniel Hailfingerf7533422010-07-17 23:21:12 +0000198 for (i = strlen("Device"); i < maxchiplen; i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000199 msg_ginfo(" ");
Uwe Hermannba290d12009-06-17 12:07:12 +0000200
Stefan Tauner29e5d312011-09-12 22:55:01 +0000201 msg_ginfo("Test");
202 for (i = 0; i < border; i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000203 msg_ginfo(" ");
Stefan Tauner29e5d312011-09-12 22:55:01 +0000204 msg_ginfo("Known");
205 for (i = 0; i < border; i++)
206 msg_ginfo(" ");
Stefan Tauner0554ca52013-07-25 22:54:25 +0000207 msg_ginfo(" Size ");
Stefan Tauner29e5d312011-09-12 22:55:01 +0000208 for (i = 0; i < border; i++)
209 msg_ginfo(" ");
210
211 msg_ginfo("Type");
212 for (i = strlen("Type"); i < maxtypelen; i++)
213 msg_ginfo(" ");
214 msg_gdbg("Voltage");
215 msg_ginfo("\n");
216
217 for (i = 0; i < maxvendorlen + maxchiplen; i++)
218 msg_ginfo(" ");
219 msg_ginfo("OK ");
220 for (i = 0; i < border; i++)
221 msg_ginfo(" ");
222 msg_ginfo("Broken");
223 for (i = 0; i < border; i++)
224 msg_ginfo(" ");
Stefan Tauner0554ca52013-07-25 22:54:25 +0000225 msg_ginfo("[kB] ");
Stefan Tauner29e5d312011-09-12 22:55:01 +0000226 for (i = 0; i < border + maxtypelen; i++)
227 msg_ginfo(" ");
228 msg_gdbg("range [V]");
229 msg_ginfo("\n\n");
Stefan Tauner5c316f92015-02-08 21:57:52 +0000230 msg_ginfo("(P = PROBE, R = READ, E = ERASE, W = WRITE, - = N/A)\n\n");
Uwe Hermannba290d12009-06-17 12:07:12 +0000231
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000232 for (chip = flashchips; chip->name != NULL; chip++) {
Stefan Tauner035492a2012-02-03 22:32:09 +0000233 /* Don't print generic entries. */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000234 if (!strncmp(chip->vendor, "Unknown", 7) ||
235 !strncmp(chip->vendor, "Programmer", 10) ||
236 !strncmp(chip->name, "unknown", 7))
Uwe Hermannba290d12009-06-17 12:07:12 +0000237 continue;
238
Stefan Tauner29e5d312011-09-12 22:55:01 +0000239 /* support for multiline vendor names:
240 * - make a copy of the original vendor name
241 * - use strok to put the first token in tmpven
242 * - keep track of the length of all tokens on the current line
243 * for ' '-padding in curvenlen
244 * - check if additional tokens should be printed on the current
245 * line
246 * - after all other values are printed print the surplus tokens
247 * on fresh lines
248 */
Stefan Tauner4a038652013-07-17 09:28:00 +0000249 ven = malloc(strlen(chip->vendor) + 1);
250 if (ven == NULL) {
Stefan Tauner29e5d312011-09-12 22:55:01 +0000251 msg_gerr("Out of memory!\n");
Niklas Söderlundede2fa42012-10-23 13:06:46 +0000252 return 1;
Stefan Tauner29e5d312011-09-12 22:55:01 +0000253 }
Stefan Tauner4a038652013-07-17 09:28:00 +0000254 strcpy(ven, chip->vendor);
Uwe Hermannba290d12009-06-17 12:07:12 +0000255
Stefan Tauner4a038652013-07-17 09:28:00 +0000256 tmpven = strtok_r(ven, delim, &tmpven_save);
Stefan Tauner29e5d312011-09-12 22:55:01 +0000257 msg_ginfo("%s", tmpven);
258 curvenlen = strlen(tmpven);
Stefan Tauner4a038652013-07-17 09:28:00 +0000259 while ((tmpven = strtok_r(NULL, delim, &tmpven_save)) != NULL) {
Stefan Tauner29e5d312011-09-12 22:55:01 +0000260 msg_ginfo("%s", delim);
261 curvenlen++;
262 tmpvenlen = strlen(tmpven);
263 if (tmpvenlen >= mintoklen)
264 break; /* big enough to be on its own line */
265 msg_ginfo("%s", tmpven);
266 curvenlen += tmpvenlen;
Uwe Hermannba290d12009-06-17 12:07:12 +0000267 }
268
Stefan Tauner29e5d312011-09-12 22:55:01 +0000269 for (i = curvenlen; i < maxvendorlen; i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000270 msg_ginfo(" ");
Stefan Tauner29e5d312011-09-12 22:55:01 +0000271
272 /* support for multiline device names as above */
Stefan Tauner4a038652013-07-17 09:28:00 +0000273 dev = malloc(strlen(chip->name) + 1);
274 if (dev == NULL) {
Stefan Tauner29e5d312011-09-12 22:55:01 +0000275 msg_gerr("Out of memory!\n");
Jacob Garber4a7970b2019-08-12 14:31:46 -0600276 free(ven);
Niklas Söderlundede2fa42012-10-23 13:06:46 +0000277 return 1;
Carl-Daniel Hailfingerf7533422010-07-17 23:21:12 +0000278 }
Stefan Tauner4a038652013-07-17 09:28:00 +0000279 strcpy(dev, chip->name);
Stefan Tauner29e5d312011-09-12 22:55:01 +0000280
Stefan Tauner4a038652013-07-17 09:28:00 +0000281 tmpdev = strtok_r(dev, delim, &tmpdev_save);
Stefan Tauner29e5d312011-09-12 22:55:01 +0000282 msg_ginfo("%s", tmpdev);
283 curdevlen = strlen(tmpdev);
Stefan Tauner4a038652013-07-17 09:28:00 +0000284 while ((tmpdev = strtok_r(NULL, delim, &tmpdev_save)) != NULL) {
Stefan Tauner29e5d312011-09-12 22:55:01 +0000285 msg_ginfo("%s", delim);
286 curdevlen++;
287 tmpdevlen = strlen(tmpdev);
288 if (tmpdevlen >= mintoklen)
289 break; /* big enough to be on its own line */
290 msg_ginfo("%s", tmpdev);
291 curdevlen += tmpdevlen;
292 }
293
294 for (i = curdevlen; i < maxchiplen; i++)
295 msg_ginfo(" ");
296
Stefan Tauner6455dff2014-05-26 00:36:24 +0000297 if (chip->tested.probe == OK)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000298 msg_ginfo("P");
Stefan Tauner6455dff2014-05-26 00:36:24 +0000299 else if (chip->tested.probe == NA)
300 msg_ginfo("-");
Stefan Tauner29e5d312011-09-12 22:55:01 +0000301 else
302 msg_ginfo(" ");
Stefan Tauner6455dff2014-05-26 00:36:24 +0000303 if (chip->tested.read == OK)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000304 msg_ginfo("R");
Stefan Tauner6455dff2014-05-26 00:36:24 +0000305 else if (chip->tested.read == NA)
306 msg_ginfo("-");
Stefan Tauner29e5d312011-09-12 22:55:01 +0000307 else
308 msg_ginfo(" ");
Stefan Tauner6455dff2014-05-26 00:36:24 +0000309 if (chip->tested.erase == OK)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000310 msg_ginfo("E");
Stefan Tauner6455dff2014-05-26 00:36:24 +0000311 else if (chip->tested.erase == NA)
312 msg_ginfo("-");
Stefan Tauner29e5d312011-09-12 22:55:01 +0000313 else
314 msg_ginfo(" ");
Stefan Tauner6455dff2014-05-26 00:36:24 +0000315 if (chip->tested.write == OK)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000316 msg_ginfo("W");
Stefan Tauner6455dff2014-05-26 00:36:24 +0000317 else if (chip->tested.write == NA)
318 msg_ginfo("-");
Stefan Tauner29e5d312011-09-12 22:55:01 +0000319 else
320 msg_ginfo(" ");
321 for (i = 0; i < border; i++)
322 msg_ginfo(" ");
323
Stefan Tauner6455dff2014-05-26 00:36:24 +0000324 if (chip->tested.probe == BAD)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000325 msg_ginfo("P");
326 else
327 msg_ginfo(" ");
Stefan Tauner6455dff2014-05-26 00:36:24 +0000328 if (chip->tested.read == BAD)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000329 msg_ginfo("R");
330 else
331 msg_ginfo(" ");
Stefan Tauner6455dff2014-05-26 00:36:24 +0000332 if (chip->tested.erase == BAD)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000333 msg_ginfo("E");
334 else
335 msg_ginfo(" ");
Stefan Tauner6455dff2014-05-26 00:36:24 +0000336 if (chip->tested.write == BAD)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000337 msg_ginfo("W");
338 else
339 msg_ginfo(" ");
340 for (i = 0; i < border + 1; i++)
341 msg_ginfo(" ");
342
Stefan Tauner0554ca52013-07-25 22:54:25 +0000343 msg_ginfo("%6d", chip->total_size);
Stefan Tauner29e5d312011-09-12 22:55:01 +0000344 for (i = 0; i < border; i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000345 msg_ginfo(" ");
Stefan Tauner00155492011-06-26 20:45:35 +0000346
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000347 s = flashbuses_to_text(chip->bustype);
Stefan Tauner29e5d312011-09-12 22:55:01 +0000348 msg_ginfo("%s", s);
349 for (i = strlen(s); i < maxtypelen; i++)
350 msg_ginfo(" ");
Stefan Tauner00155492011-06-26 20:45:35 +0000351 free(s);
Stefan Tauner29e5d312011-09-12 22:55:01 +0000352
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000353 if (chip->voltage.min == 0 && chip->voltage.max == 0)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000354 msg_gdbg("no info");
355 else
356 msg_gdbg("%0.02f;%0.02f",
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000357 chip->voltage.min/(double)1000,
358 chip->voltage.max/(double)1000);
Stefan Tauner29e5d312011-09-12 22:55:01 +0000359
360 /* print surplus vendor and device name tokens */
361 while (tmpven != NULL || tmpdev != NULL) {
362 msg_ginfo("\n");
363 if (tmpven != NULL){
364 msg_ginfo("%s", tmpven);
365 curvenlen = strlen(tmpven);
Stefan Tauner4a038652013-07-17 09:28:00 +0000366 while ((tmpven = strtok_r(NULL, delim, &tmpven_save)) != NULL) {
Stefan Tauner29e5d312011-09-12 22:55:01 +0000367 msg_ginfo("%s", delim);
368 curvenlen++;
369 tmpvenlen = strlen(tmpven);
370 /* big enough to be on its own line */
371 if (tmpvenlen >= mintoklen)
372 break;
373 msg_ginfo("%s", tmpven);
374 curvenlen += tmpvenlen;
375 }
376 } else
377 curvenlen = 0;
378
379 for (i = curvenlen; i < maxvendorlen; i++)
380 msg_ginfo(" ");
381
382 if (tmpdev != NULL){
383 msg_ginfo("%s", tmpdev);
384 curdevlen = strlen(tmpdev);
Stefan Tauner4a038652013-07-17 09:28:00 +0000385 while ((tmpdev = strtok_r(NULL, delim, &tmpdev_save)) != NULL) {
Stefan Tauner29e5d312011-09-12 22:55:01 +0000386 msg_ginfo("%s", delim);
387 curdevlen++;
388 tmpdevlen = strlen(tmpdev);
389 /* big enough to be on its own line */
390 if (tmpdevlen >= mintoklen)
391 break;
392 msg_ginfo("%s", tmpdev);
393 curdevlen += tmpdevlen;
394 }
395 }
396 }
397 msg_ginfo("\n");
Stefan Tauner4a038652013-07-17 09:28:00 +0000398 free(ven);
399 free(dev);
Uwe Hermannba290d12009-06-17 12:07:12 +0000400 }
Niklas Söderlundede2fa42012-10-23 13:06:46 +0000401
402 return 0;
Uwe Hermannba290d12009-06-17 12:07:12 +0000403}
404
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +0000405#if CONFIG_INTERNAL == 1
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000406static void print_supported_chipsets(void)
Uwe Hermannba290d12009-06-17 12:07:12 +0000407{
Nico Huber519be662018-12-23 20:03:35 +0100408 unsigned int i, chipsetcount = 0;
Uwe Hermannba290d12009-06-17 12:07:12 +0000409 const struct penable *c = chipset_enables;
Nico Huber519be662018-12-23 20:03:35 +0100410 size_t maxvendorlen = strlen("Vendor") + 1;
411 size_t maxchipsetlen = strlen("Chipset") + 1;
Uwe Hermannba290d12009-06-17 12:07:12 +0000412
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000413 for (c = chipset_enables; c->vendor_name != NULL; c++) {
Uwe Hermannba290d12009-06-17 12:07:12 +0000414 chipsetcount++;
Nico Huber519be662018-12-23 20:03:35 +0100415 maxvendorlen = MAX(maxvendorlen, strlen(c->vendor_name));
416 maxchipsetlen = MAX(maxchipsetlen, strlen(c->device_name));
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000417 }
418 maxvendorlen++;
419 maxchipsetlen++;
Uwe Hermannba290d12009-06-17 12:07:12 +0000420
Nico Huber519be662018-12-23 20:03:35 +0100421 msg_ginfo("Supported chipsets (total: %u):\n\n", chipsetcount);
Uwe Hermannba290d12009-06-17 12:07:12 +0000422
Stefan Tauner12589362011-06-25 17:36:25 +0000423 msg_ginfo("Vendor");
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000424 for (i = strlen("Vendor"); i < maxvendorlen; i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000425 msg_ginfo(" ");
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000426
Stefan Tauner12589362011-06-25 17:36:25 +0000427 msg_ginfo("Chipset");
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000428 for (i = strlen("Chipset"); i < maxchipsetlen; i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000429 msg_ginfo(" ");
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000430
Stefan Tauner428ba2b2014-06-02 00:34:58 +0000431 msg_ginfo("PCI IDs Status\n\n");
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000432
433 for (c = chipset_enables; c->vendor_name != NULL; c++) {
Stefan Tauner12589362011-06-25 17:36:25 +0000434 msg_ginfo("%s", c->vendor_name);
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000435 for (i = 0; i < maxvendorlen - strlen(c->vendor_name); i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000436 msg_ginfo(" ");
437 msg_ginfo("%s", c->device_name);
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000438 for (i = 0; i < maxchipsetlen - strlen(c->device_name); i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000439 msg_ginfo(" ");
Stefan Tauner428ba2b2014-06-02 00:34:58 +0000440 msg_ginfo("%04x:%04x %s\n", c->vendor_id, c->device_id,
441 test_state_to_text(c->status));
Uwe Hermannba290d12009-06-17 12:07:12 +0000442 }
443}
444
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000445static void print_supported_boards_helper(const struct board_info *boards,
Peter Lemenkov4adf8a62010-06-01 10:13:17 +0000446 const char *devicetype)
Uwe Hermannba290d12009-06-17 12:07:12 +0000447{
Nico Huber519be662018-12-23 20:03:35 +0100448 unsigned int i;
Stefan Tauner2c20b282012-07-28 19:35:26 +0000449 unsigned int boardcount_good = 0, boardcount_bad = 0, boardcount_nt = 0;
Carl-Daniel Hailfinger97d5b122011-08-31 16:19:50 +0000450 const struct board_match *e = board_matches;
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000451 const struct board_info *b = boards;
Nico Huber519be662018-12-23 20:03:35 +0100452 size_t maxvendorlen = strlen("Vendor") + 1;
453 size_t maxboardlen = strlen("Board") + 1;
Uwe Hermannba290d12009-06-17 12:07:12 +0000454
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000455 for (b = boards; b->vendor != NULL; b++) {
456 maxvendorlen = max(maxvendorlen, strlen(b->vendor));
457 maxboardlen = max(maxboardlen, strlen(b->name));
Stefan Tauner2c20b282012-07-28 19:35:26 +0000458 if (b->working == OK)
Peter Lemenkov4adf8a62010-06-01 10:13:17 +0000459 boardcount_good++;
Stefan Tauner2c20b282012-07-28 19:35:26 +0000460 else if (b->working == NT)
461 boardcount_nt++;
Uwe Hermannba290d12009-06-17 12:07:12 +0000462 else
Peter Lemenkov4adf8a62010-06-01 10:13:17 +0000463 boardcount_bad++;
Uwe Hermannba290d12009-06-17 12:07:12 +0000464 }
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000465 maxvendorlen++;
466 maxboardlen++;
Uwe Hermannba290d12009-06-17 12:07:12 +0000467
Stefan Tauner2c20b282012-07-28 19:35:26 +0000468 msg_ginfo("%d known %s (good: %d, untested: %d, bad: %d):\n\n",
469 boardcount_good + boardcount_nt + boardcount_bad,
470 devicetype, boardcount_good, boardcount_nt, boardcount_bad);
Peter Lemenkov4adf8a62010-06-01 10:13:17 +0000471
Stefan Tauner12589362011-06-25 17:36:25 +0000472 msg_ginfo("Vendor");
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000473 for (i = strlen("Vendor"); i < maxvendorlen; i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000474 msg_ginfo(" ");
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000475
Stefan Tauner12589362011-06-25 17:36:25 +0000476 msg_ginfo("Board");
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000477 for (i = strlen("Board"); i < maxboardlen; i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000478 msg_ginfo(" ");
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000479
Carl-Daniel Hailfinger2d927fb2012-01-04 00:48:27 +0000480 msg_ginfo("Status Required value for\n");
481 for (i = 0; i < maxvendorlen + maxboardlen + strlen("Status "); i++)
482 msg_ginfo(" ");
483 msg_ginfo("-p internal:mainboard=\n");
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000484
485 for (b = boards; b->vendor != NULL; b++) {
Stefan Tauner12589362011-06-25 17:36:25 +0000486 msg_ginfo("%s", b->vendor);
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000487 for (i = 0; i < maxvendorlen - strlen(b->vendor); i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000488 msg_ginfo(" ");
489 msg_ginfo("%s", b->name);
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000490 for (i = 0; i < maxboardlen - strlen(b->name); i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000491 msg_ginfo(" ");
Stefan Reinauerf94d9ce2014-04-26 16:11:07 +0000492
Nico Huber5d068dd2019-11-17 13:39:46 +0100493 switch (b->working) {
494 case OK: msg_ginfo("OK "); break;
495 case NT: msg_ginfo("NT "); break;
496 case DEP: msg_ginfo("DEP "); break;
497 case NA: msg_ginfo("N/A "); break;
498 case BAD:
499 default: msg_ginfo("BAD "); break;
500 }
Peter Lemenkov4adf8a62010-06-01 10:13:17 +0000501
Carl-Daniel Hailfinger97d5b122011-08-31 16:19:50 +0000502 for (e = board_matches; e->vendor_name != NULL; e++) {
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000503 if (strcmp(e->vendor_name, b->vendor)
504 || strcmp(e->board_name, b->name))
Peter Lemenkov4adf8a62010-06-01 10:13:17 +0000505 continue;
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000506 if (e->lb_vendor == NULL)
Stefan Tauner12589362011-06-25 17:36:25 +0000507 msg_ginfo("(autodetected)");
Peter Lemenkov4adf8a62010-06-01 10:13:17 +0000508 else
Carl-Daniel Hailfinger2d927fb2012-01-04 00:48:27 +0000509 msg_ginfo("%s:%s", e->lb_vendor,
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000510 e->lb_part);
Peter Lemenkov4adf8a62010-06-01 10:13:17 +0000511 }
Stefan Tauner12589362011-06-25 17:36:25 +0000512 msg_ginfo("\n");
Peter Lemenkov4adf8a62010-06-01 10:13:17 +0000513 }
Uwe Hermannba290d12009-06-17 12:07:12 +0000514}
Carl-Daniel Hailfinger66ef4e52009-12-13 22:28:00 +0000515#endif
Uwe Hermannd0e347d2009-10-06 13:00:00 +0000516
Thomas Heijligen633d6db2021-03-31 19:09:44 +0200517static void print_supported_devs(const struct programmer_entry *const prog, const char *const type)
Stefan Tauneraf358d62012-12-27 18:40:26 +0000518{
Thomas Heijligen633d6db2021-03-31 19:09:44 +0200519 const struct dev_entry *const devs = prog->devs.dev;
520 msg_ginfo("\nSupported %s devices for the %s programmer:\n", type, prog->name);
Stefan Tauner1181ee22014-06-01 02:13:23 +0000521 unsigned int maxvendorlen = strlen("Vendor") + 1;
522 unsigned int maxdevlen = strlen("Device") + 1;
523
524 unsigned int i;
Stefan Tauneraf358d62012-12-27 18:40:26 +0000525 for (i = 0; devs[i].vendor_name != NULL; i++) {
Stefan Tauner1181ee22014-06-01 02:13:23 +0000526 maxvendorlen = max(maxvendorlen, strlen(devs[i].vendor_name));
527 maxdevlen = max(maxdevlen, strlen(devs[i].device_name));
528 }
529 maxvendorlen++;
530 maxdevlen++;
531
532 msg_ginfo("Vendor");
533 for (i = strlen("Vendor"); i < maxvendorlen; i++)
534 msg_ginfo(" ");
535
536 msg_ginfo("Device");
537 for (i = strlen("Device"); i < maxdevlen; i++)
538 msg_ginfo(" ");
539
540 msg_ginfo(" %s IDs Status\n", type);
541
542 for (i = 0; devs[i].vendor_name != NULL; i++) {
543 msg_ginfo("%s", devs[i].vendor_name);
544 unsigned int j;
545 for (j = strlen(devs[i].vendor_name); j < maxvendorlen; j++)
546 msg_ginfo(" ");
547 msg_ginfo("%s", devs[i].device_name);
548 for (j = strlen(devs[i].device_name); j < maxdevlen; j++)
549 msg_ginfo(" ");
550
551 msg_pinfo(" %04x:%04x %s\n", devs[i].vendor_id, devs[i].device_id,
552 test_state_to_text(devs[i].status));
Stefan Tauneraf358d62012-12-27 18:40:26 +0000553 }
554}
555
Niklas Söderlundede2fa42012-10-23 13:06:46 +0000556int print_supported(void)
Carl-Daniel Hailfingerf5292052009-11-17 09:57:34 +0000557{
Stefan Tauneraf358d62012-12-27 18:40:26 +0000558 unsigned int i;
Niklas Söderlundede2fa42012-10-23 13:06:46 +0000559 if (print_supported_chips())
560 return 1;
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +0000561
Stefan Tauner12589362011-06-25 17:36:25 +0000562 msg_ginfo("\nSupported programmers:\n");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +0000563 list_programmers_linebreak(0, 80, 0);
Stefan Taunerb226cb12012-11-24 18:59:39 +0000564 msg_ginfo("\n");
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +0000565#if CONFIG_INTERNAL == 1
Thomas Heijligen79088ab2021-06-01 13:57:42 +0200566 msg_ginfo("\nSupported devices for the internal programmer:\n\n");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +0000567 print_supported_chipsets();
Stefan Tauner12589362011-06-25 17:36:25 +0000568 msg_ginfo("\n");
Stefan Tauner74dc73f2015-03-01 22:04:38 +0000569 print_supported_boards_helper(boards_known, "mainboards");
Stefan Tauner12589362011-06-25 17:36:25 +0000570 msg_ginfo("\n");
Stefan Tauner74dc73f2015-03-01 22:04:38 +0000571 print_supported_boards_helper(laptops_known, "mobile devices");
Carl-Daniel Hailfinger66ef4e52009-12-13 22:28:00 +0000572#endif
Thomas Heijligend45cb592021-05-19 14:12:18 +0200573 for (i = 0; i < programmer_table_size; i++) {
Thomas Heijligen633d6db2021-03-31 19:09:44 +0200574 const struct programmer_entry *const prog = programmer_table[i];
575 switch (prog->type) {
Stefan Tauneraf358d62012-12-27 18:40:26 +0000576 case USB:
Stefan Tauner4b24a2d2012-12-27 18:40:36 +0000577 print_supported_devs(prog, "USB");
Stefan Tauneraf358d62012-12-27 18:40:26 +0000578 break;
Stefan Tauneraf358d62012-12-27 18:40:26 +0000579 case PCI:
Stefan Tauner4b24a2d2012-12-27 18:40:36 +0000580 print_supported_devs(prog, "PCI");
Stefan Tauneraf358d62012-12-27 18:40:26 +0000581 break;
Stefan Tauneraf358d62012-12-27 18:40:26 +0000582 case OTHER:
Thomas Heijligen633d6db2021-03-31 19:09:44 +0200583 if (prog->devs.note != NULL) {
584 msg_ginfo("\nSupported devices for the %s programmer:\n", prog->name);
585 msg_ginfo("%s", prog->devs.note);
Stefan Tauner4b24a2d2012-12-27 18:40:36 +0000586 }
Stefan Tauneraf358d62012-12-27 18:40:26 +0000587 break;
588 default:
Nico Huberac90af62022-12-18 00:22:47 +0000589 msg_gerr("\n%s: %s: Uninitialized programmer type!\n"
590 "Please report a bug at flashrom-stable@flashrom.org\n",
591 __func__, prog->name);
Stefan Tauneraf358d62012-12-27 18:40:26 +0000592 break;
593 }
594 }
Niklas Söderlundede2fa42012-10-23 13:06:46 +0000595 return 0;
Carl-Daniel Hailfingerf5292052009-11-17 09:57:34 +0000596}