blob: d6c954244259bd2fb1aa3f6b9cdf312214c86ba5 [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))
Thomas Heijligen78ed6682022-08-08 21:55:07 +020045 msg_ginfo(" %lu.%lu", (unsigned long)osvi.dwMajorVersion,
46 (unsigned long)osvi.dwMinorVersion);
Edward O'Callaghan3b64d812022-08-12 13:07:51 +100047 else
48 msg_ginfo(" unknown version");
49 GetSystemInfo(&si);
50 switch (si.wProcessorArchitecture) {
51 case PROCESSOR_ARCHITECTURE_AMD64:
52 msg_ginfo(" (x86_64)");
53 break;
54 case PROCESSOR_ARCHITECTURE_INTEL:
55 msg_ginfo(" (x86)");
56 break;
57 default:
58 msg_ginfo(" (unknown arch)");
59 break;
60 }
61#elif HAVE_UTSNAME == 1
62 struct utsname osinfo;
63
64 uname(&osinfo);
65 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
66 osinfo.machine);
67#else
68 msg_ginfo(" on unknown machine");
69#endif
70}
71
72void print_buildinfo(void)
73{
Nico Huberc3b02dc2023-08-12 01:13:45 +020074 msg_gdbg("flashprog was built with");
Edward O'Callaghan3b64d812022-08-12 13:07:51 +100075#ifdef __clang__
76 msg_gdbg(" LLVM Clang");
77#ifdef __clang_version__
78 msg_gdbg(" %s,", __clang_version__);
79#else
80 msg_gdbg(" unknown version (before r102686),");
81#endif
82#elif defined(__GNUC__)
83 msg_gdbg(" GCC");
84#ifdef __VERSION__
85 msg_gdbg(" %s,", __VERSION__);
86#else
87 msg_gdbg(" unknown version,");
88#endif
89#else
90 msg_gdbg(" unknown compiler,");
91#endif
Nico Huberc3b02dc2023-08-12 01:13:45 +020092#if defined (__FLASHPROG_LITTLE_ENDIAN__)
Edward O'Callaghan3b64d812022-08-12 13:07:51 +100093 msg_gdbg(" little endian");
Nico Huberc3b02dc2023-08-12 01:13:45 +020094#elif defined (__FLASHPROG_BIG_ENDIAN__)
Edward O'Callaghan3b64d812022-08-12 13:07:51 +100095 msg_gdbg(" big endian");
96#else
97#error Endianness could not be determined
98#endif
99 msg_gdbg("\n");
100}
101
102void print_version(void)
103{
Nico Huberc3b02dc2023-08-12 01:13:45 +0200104 msg_ginfo("flashprog %s", flashprog_version);
Edward O'Callaghan3b64d812022-08-12 13:07:51 +1000105 print_sysinfo();
106 msg_ginfo("\n");
107}
108
109void print_banner(void)
110{
Nico Huberc3b02dc2023-08-12 01:13:45 +0200111 msg_ginfo("flashprog is free software, get the source code at "
112 "https://flashprog.org\n");
Edward O'Callaghan3b64d812022-08-12 13:07:51 +1000113 msg_ginfo("\n");
114}
115
Nico Huber0d2b45e2026-03-23 22:42:46 +0100116static const char *test_state_to_text(enum flashprog_test_state test_state)
Stefan Tauner1181ee22014-06-01 02:13:23 +0000117{
118 switch (test_state) {
119 case OK: return "OK";
120 case BAD: return "Not working";
121 case NA: return "N/A";
122 case DEP: return "Config-dependent";
123 case NT:
124 default: return "Untested";
125 }
126}
127
Niklas Söderlundede2fa42012-10-23 13:06:46 +0000128static int print_supported_chips(void)
Uwe Hermannba290d12009-06-17 12:07:12 +0000129{
Stefan Tauner29e5d312011-09-12 22:55:01 +0000130 const char *delim = "/";
131 const int mintoklen = 5;
132 const int border = 2;
133 int i, chipcount = 0;
Stefan Tauner7bcacb12011-05-26 01:35:19 +0000134 int maxvendorlen = strlen("Vendor") + 1;
135 int maxchiplen = strlen("Device") + 1;
Stefan Tauner29e5d312011-09-12 22:55:01 +0000136 int maxtypelen = strlen("Type") + 1;
Nico Huber43fedab2026-03-23 23:22:50 +0100137 struct flashprog_voltage_range voltage;
138 struct flashprog_test_status tested;
139 const struct flashprog_chip *chip;
140 struct flashprog_chips *chips;
Stefan Tauner00155492011-06-26 20:45:35 +0000141 char *s;
Stefan Tauner4a038652013-07-17 09:28:00 +0000142 char *ven, *dev;
Nico Huber43fedab2026-03-23 23:22:50 +0100143 const char *tmpven, *tmpdev;
144 char *tmpven_save, *tmpdev_save;
Stefan Tauner29e5d312011-09-12 22:55:01 +0000145 int tmpvenlen, tmpdevlen, curvenlen, curdevlen;
Uwe Hermannba290d12009-06-17 12:07:12 +0000146
Nico Huber43fedab2026-03-23 23:22:50 +0100147 if (flashprog_chips_all(&chips))
148 return 1;
149
Stefan Tauner29e5d312011-09-12 22:55:01 +0000150 /* calculate maximum column widths and by iterating over all chips */
Nico Huber43fedab2026-03-23 23:22:50 +0100151 for (chip = flashprog_chip_first(chips); chip; chip = flashprog_chip_next(chip)) {
Uwe Hermannba290d12009-06-17 12:07:12 +0000152 chipcount++;
Stefan Tauner29e5d312011-09-12 22:55:01 +0000153
154 /* Find maximum vendor length (respecting line splitting). */
Nico Huber43fedab2026-03-23 23:22:50 +0100155 tmpven = flashprog_chip_vendor(chip);
Stefan Tauner29e5d312011-09-12 22:55:01 +0000156 do {
157 /* and take minimum token lengths into account */
158 tmpvenlen = 0;
159 do {
160 tmpvenlen += strcspn(tmpven, delim);
161 /* skip to the address after the first token */
162 tmpven += tmpvenlen;
163 if (tmpven[0] == '\0')
164 break;
165 tmpven++;
166 } while (tmpvenlen < mintoklen);
167 maxvendorlen = max(maxvendorlen, tmpvenlen);
168 if (tmpven[0] == '\0')
169 break;
170 } while (1);
171
172 /* same for device name */
Nico Huber43fedab2026-03-23 23:22:50 +0100173 tmpdev = flashprog_chip_name(chip);
Stefan Tauner29e5d312011-09-12 22:55:01 +0000174 do {
175 tmpdevlen = 0;
176 do {
177 tmpdevlen += strcspn(tmpdev, delim);
178 tmpdev += tmpdevlen;
179 if (tmpdev[0] == '\0')
180 break;
181 tmpdev++;
182 } while (tmpdevlen < mintoklen);
183 maxchiplen = max(maxchiplen, tmpdevlen);
184 if (tmpdev[0] == '\0')
185 break;
186 } while (1);
187
Nico Huber43fedab2026-03-23 23:22:50 +0100188 s = flashprog_chip_bus_names(chip);
Stefan Tauner29e5d312011-09-12 22:55:01 +0000189 maxtypelen = max(maxtypelen, strlen(s));
190 free(s);
Carl-Daniel Hailfingerf7533422010-07-17 23:21:12 +0000191 }
Stefan Tauner29e5d312011-09-12 22:55:01 +0000192 maxvendorlen += border;
193 maxchiplen += border;
194 maxtypelen += border;
Uwe Hermannba290d12009-06-17 12:07:12 +0000195
Stefan Tauner12589362011-06-25 17:36:25 +0000196 msg_ginfo("Supported flash chips (total: %d):\n\n", chipcount);
197 msg_ginfo("Vendor");
Carl-Daniel Hailfingerf7533422010-07-17 23:21:12 +0000198 for (i = strlen("Vendor"); i < maxvendorlen; i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000199 msg_ginfo(" ");
200 msg_ginfo("Device");
Carl-Daniel Hailfingerf7533422010-07-17 23:21:12 +0000201 for (i = strlen("Device"); i < maxchiplen; i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000202 msg_ginfo(" ");
Uwe Hermannba290d12009-06-17 12:07:12 +0000203
Stefan Tauner29e5d312011-09-12 22:55:01 +0000204 msg_ginfo("Test");
205 for (i = 0; i < border; i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000206 msg_ginfo(" ");
Stefan Tauner29e5d312011-09-12 22:55:01 +0000207 msg_ginfo("Known");
208 for (i = 0; i < border; i++)
209 msg_ginfo(" ");
Stefan Tauner0554ca52013-07-25 22:54:25 +0000210 msg_ginfo(" Size ");
Stefan Tauner29e5d312011-09-12 22:55:01 +0000211 for (i = 0; i < border; i++)
212 msg_ginfo(" ");
213
214 msg_ginfo("Type");
215 for (i = strlen("Type"); i < maxtypelen; i++)
216 msg_ginfo(" ");
217 msg_gdbg("Voltage");
218 msg_ginfo("\n");
219
220 for (i = 0; i < maxvendorlen + maxchiplen; i++)
221 msg_ginfo(" ");
222 msg_ginfo("OK ");
223 for (i = 0; i < border; i++)
224 msg_ginfo(" ");
225 msg_ginfo("Broken");
226 for (i = 0; i < border; i++)
227 msg_ginfo(" ");
Stefan Tauner0554ca52013-07-25 22:54:25 +0000228 msg_ginfo("[kB] ");
Stefan Tauner29e5d312011-09-12 22:55:01 +0000229 for (i = 0; i < border + maxtypelen; i++)
230 msg_ginfo(" ");
231 msg_gdbg("range [V]");
232 msg_ginfo("\n\n");
Stefan Tauner5c316f92015-02-08 21:57:52 +0000233 msg_ginfo("(P = PROBE, R = READ, E = ERASE, W = WRITE, - = N/A)\n\n");
Uwe Hermannba290d12009-06-17 12:07:12 +0000234
Nico Huber43fedab2026-03-23 23:22:50 +0100235 for (chip = flashprog_chip_first(chips); chip; chip = flashprog_chip_next(chip)) {
Stefan Tauner29e5d312011-09-12 22:55:01 +0000236 /* support for multiline vendor names:
237 * - make a copy of the original vendor name
238 * - use strok to put the first token in tmpven
239 * - keep track of the length of all tokens on the current line
240 * for ' '-padding in curvenlen
241 * - check if additional tokens should be printed on the current
242 * line
243 * - after all other values are printed print the surplus tokens
244 * on fresh lines
245 */
Nico Huber43fedab2026-03-23 23:22:50 +0100246 ven = malloc(strlen(flashprog_chip_vendor(chip)) + 1);
Stefan Tauner4a038652013-07-17 09:28:00 +0000247 if (ven == NULL) {
Stefan Tauner29e5d312011-09-12 22:55:01 +0000248 msg_gerr("Out of memory!\n");
Nico Huber43fedab2026-03-23 23:22:50 +0100249 flashprog_chips_release(chips);
Niklas Söderlundede2fa42012-10-23 13:06:46 +0000250 return 1;
Stefan Tauner29e5d312011-09-12 22:55:01 +0000251 }
Nico Huber43fedab2026-03-23 23:22:50 +0100252 strcpy(ven, flashprog_chip_vendor(chip));
Uwe Hermannba290d12009-06-17 12:07:12 +0000253
Stefan Tauner4a038652013-07-17 09:28:00 +0000254 tmpven = strtok_r(ven, delim, &tmpven_save);
Stefan Tauner29e5d312011-09-12 22:55:01 +0000255 msg_ginfo("%s", tmpven);
256 curvenlen = strlen(tmpven);
Stefan Tauner4a038652013-07-17 09:28:00 +0000257 while ((tmpven = strtok_r(NULL, delim, &tmpven_save)) != NULL) {
Stefan Tauner29e5d312011-09-12 22:55:01 +0000258 msg_ginfo("%s", delim);
259 curvenlen++;
260 tmpvenlen = strlen(tmpven);
261 if (tmpvenlen >= mintoklen)
262 break; /* big enough to be on its own line */
263 msg_ginfo("%s", tmpven);
264 curvenlen += tmpvenlen;
Uwe Hermannba290d12009-06-17 12:07:12 +0000265 }
266
Stefan Tauner29e5d312011-09-12 22:55:01 +0000267 for (i = curvenlen; i < maxvendorlen; i++)
Stefan Tauner12589362011-06-25 17:36:25 +0000268 msg_ginfo(" ");
Stefan Tauner29e5d312011-09-12 22:55:01 +0000269
270 /* support for multiline device names as above */
Nico Huber43fedab2026-03-23 23:22:50 +0100271 dev = malloc(strlen(flashprog_chip_name(chip)) + 1);
Stefan Tauner4a038652013-07-17 09:28:00 +0000272 if (dev == NULL) {
Stefan Tauner29e5d312011-09-12 22:55:01 +0000273 msg_gerr("Out of memory!\n");
Nico Huber43fedab2026-03-23 23:22:50 +0100274 flashprog_chips_release(chips);
Jacob Garber4a7970b2019-08-12 14:31:46 -0600275 free(ven);
Niklas Söderlundede2fa42012-10-23 13:06:46 +0000276 return 1;
Carl-Daniel Hailfingerf7533422010-07-17 23:21:12 +0000277 }
Nico Huber43fedab2026-03-23 23:22:50 +0100278 strcpy(dev, flashprog_chip_name(chip));
Stefan Tauner29e5d312011-09-12 22:55:01 +0000279
Stefan Tauner4a038652013-07-17 09:28:00 +0000280 tmpdev = strtok_r(dev, delim, &tmpdev_save);
Stefan Tauner29e5d312011-09-12 22:55:01 +0000281 msg_ginfo("%s", tmpdev);
282 curdevlen = strlen(tmpdev);
Stefan Tauner4a038652013-07-17 09:28:00 +0000283 while ((tmpdev = strtok_r(NULL, delim, &tmpdev_save)) != NULL) {
Stefan Tauner29e5d312011-09-12 22:55:01 +0000284 msg_ginfo("%s", delim);
285 curdevlen++;
286 tmpdevlen = strlen(tmpdev);
287 if (tmpdevlen >= mintoklen)
288 break; /* big enough to be on its own line */
289 msg_ginfo("%s", tmpdev);
290 curdevlen += tmpdevlen;
291 }
292
293 for (i = curdevlen; i < maxchiplen; i++)
294 msg_ginfo(" ");
295
Nico Huber43fedab2026-03-23 23:22:50 +0100296 tested = flashprog_chip_test_status(chip);
297 if (tested.probe == OK)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000298 msg_ginfo("P");
Nico Huber43fedab2026-03-23 23:22:50 +0100299 else if (tested.probe == NA)
Stefan Tauner6455dff2014-05-26 00:36:24 +0000300 msg_ginfo("-");
Stefan Tauner29e5d312011-09-12 22:55:01 +0000301 else
302 msg_ginfo(" ");
Nico Huber43fedab2026-03-23 23:22:50 +0100303 if (tested.read == OK)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000304 msg_ginfo("R");
Nico Huber43fedab2026-03-23 23:22:50 +0100305 else if (tested.read == NA)
Stefan Tauner6455dff2014-05-26 00:36:24 +0000306 msg_ginfo("-");
Stefan Tauner29e5d312011-09-12 22:55:01 +0000307 else
308 msg_ginfo(" ");
Nico Huber43fedab2026-03-23 23:22:50 +0100309 if (tested.erase == OK)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000310 msg_ginfo("E");
Nico Huber43fedab2026-03-23 23:22:50 +0100311 else if (tested.erase == NA)
Stefan Tauner6455dff2014-05-26 00:36:24 +0000312 msg_ginfo("-");
Stefan Tauner29e5d312011-09-12 22:55:01 +0000313 else
314 msg_ginfo(" ");
Nico Huber43fedab2026-03-23 23:22:50 +0100315 if (tested.write == OK)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000316 msg_ginfo("W");
Nico Huber43fedab2026-03-23 23:22:50 +0100317 else if (tested.write == NA)
Stefan Tauner6455dff2014-05-26 00:36:24 +0000318 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
Nico Huber43fedab2026-03-23 23:22:50 +0100324 if (tested.probe == BAD)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000325 msg_ginfo("P");
326 else
327 msg_ginfo(" ");
Nico Huber43fedab2026-03-23 23:22:50 +0100328 if (tested.read == BAD)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000329 msg_ginfo("R");
330 else
331 msg_ginfo(" ");
Nico Huber43fedab2026-03-23 23:22:50 +0100332 if (tested.erase == BAD)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000333 msg_ginfo("E");
334 else
335 msg_ginfo(" ");
Nico Huber43fedab2026-03-23 23:22:50 +0100336 if (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
Nico Huber43fedab2026-03-23 23:22:50 +0100343 msg_ginfo("%6zu", flashprog_chip_size(chip) / KiB);
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
Nico Huber43fedab2026-03-23 23:22:50 +0100347 s = flashprog_chip_bus_names(chip);
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
Nico Huber43fedab2026-03-23 23:22:50 +0100353 voltage = flashprog_chip_voltage_range(chip);
354 if (voltage.min == 0 && voltage.max == 0)
Stefan Tauner29e5d312011-09-12 22:55:01 +0000355 msg_gdbg("no info");
356 else
Nico Huber43fedab2026-03-23 23:22:50 +0100357 msg_gdbg("%0.02f;%0.02f", voltage.min, voltage.max);
Stefan Tauner29e5d312011-09-12 22:55:01 +0000358
359 /* print surplus vendor and device name tokens */
360 while (tmpven != NULL || tmpdev != NULL) {
361 msg_ginfo("\n");
362 if (tmpven != NULL){
363 msg_ginfo("%s", tmpven);
364 curvenlen = strlen(tmpven);
Stefan Tauner4a038652013-07-17 09:28:00 +0000365 while ((tmpven = strtok_r(NULL, delim, &tmpven_save)) != NULL) {
Stefan Tauner29e5d312011-09-12 22:55:01 +0000366 msg_ginfo("%s", delim);
367 curvenlen++;
368 tmpvenlen = strlen(tmpven);
369 /* big enough to be on its own line */
370 if (tmpvenlen >= mintoklen)
371 break;
372 msg_ginfo("%s", tmpven);
373 curvenlen += tmpvenlen;
374 }
375 } else
376 curvenlen = 0;
377
378 for (i = curvenlen; i < maxvendorlen; i++)
379 msg_ginfo(" ");
380
381 if (tmpdev != NULL){
382 msg_ginfo("%s", tmpdev);
383 curdevlen = strlen(tmpdev);
Stefan Tauner4a038652013-07-17 09:28:00 +0000384 while ((tmpdev = strtok_r(NULL, delim, &tmpdev_save)) != NULL) {
Stefan Tauner29e5d312011-09-12 22:55:01 +0000385 msg_ginfo("%s", delim);
386 curdevlen++;
387 tmpdevlen = strlen(tmpdev);
388 /* big enough to be on its own line */
389 if (tmpdevlen >= mintoklen)
390 break;
391 msg_ginfo("%s", tmpdev);
392 curdevlen += tmpdevlen;
393 }
394 }
395 }
396 msg_ginfo("\n");
Stefan Tauner4a038652013-07-17 09:28:00 +0000397 free(ven);
398 free(dev);
Uwe Hermannba290d12009-06-17 12:07:12 +0000399 }
Niklas Söderlundede2fa42012-10-23 13:06:46 +0000400
Nico Huber43fedab2026-03-23 23:22:50 +0100401 flashprog_chips_release(chips);
Niklas Söderlundede2fa42012-10-23 13:06:46 +0000402 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"
Nico Huberc3b02dc2023-08-12 01:13:45 +0200590 "Please report a bug at flashprog@flashprog.org\n",
Nico Huberac90af62022-12-18 00:22:47 +0000591 __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}