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 *
7*0d6140beSAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or modify
8*0d6140beSAndroid Build Coastguard Worker * it under the terms of the GNU General Public License as published by
9*0d6140beSAndroid Build Coastguard Worker * the Free Software Foundation; either version 2 of the License, or
10*0d6140beSAndroid Build Coastguard Worker * (at your option) any later version.
11*0d6140beSAndroid Build Coastguard Worker *
12*0d6140beSAndroid Build Coastguard Worker * This program is distributed in the hope that it will be useful,
13*0d6140beSAndroid Build Coastguard Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*0d6140beSAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*0d6140beSAndroid Build Coastguard Worker * GNU General Public License for more details.
16*0d6140beSAndroid Build Coastguard Worker */
17*0d6140beSAndroid Build Coastguard Worker
18*0d6140beSAndroid Build Coastguard Worker #include <stdio.h>
19*0d6140beSAndroid Build Coastguard Worker #include <string.h>
20*0d6140beSAndroid Build Coastguard Worker #include <stdlib.h>
21*0d6140beSAndroid Build Coastguard Worker #include <time.h>
22*0d6140beSAndroid Build Coastguard Worker #include "flash.h"
23*0d6140beSAndroid Build Coastguard Worker #include "flashchips.h"
24*0d6140beSAndroid Build Coastguard Worker #include "programmer.h"
25*0d6140beSAndroid Build Coastguard Worker
26*0d6140beSAndroid Build Coastguard Worker static const char wiki_header[] = "= Supported devices =\n\n\
27*0d6140beSAndroid Build Coastguard Worker <div style=\"margin-top:0.5em; padding:0.5em 0.5em 0.5em 0.5em; \
28*0d6140beSAndroid Build Coastguard Worker background-color:#eeeeee; text-align:left; border:1px solid #aabbcc;\">\
29*0d6140beSAndroid Build Coastguard Worker <small>\n\
30*0d6140beSAndroid Build Coastguard Worker '''Last update:''' %s (generated by flashrom %s)<br />\n\
31*0d6140beSAndroid Build Coastguard Worker The tables below are generated from flashrom's source by copying the output of '''flashrom -z'''.<br /><br />\n\
32*0d6140beSAndroid Build Coastguard Worker A short explanation of the cells representing the support state follows:<br />\n\
33*0d6140beSAndroid Build Coastguard Worker {| border=\"0\" valign=\"top\"\n\
34*0d6140beSAndroid Build Coastguard Worker ! style=\"text-align:left;\" |\n\
35*0d6140beSAndroid Build Coastguard Worker ! style=\"text-align:left;\" |\n\
36*0d6140beSAndroid Build Coastguard Worker |-\n\
37*0d6140beSAndroid Build Coastguard Worker |{{OK}}\n\
38*0d6140beSAndroid Build Coastguard Worker | The feature was '''tested and should work''' in general unless there is a bug in flashrom or another component in \
39*0d6140beSAndroid Build Coastguard Worker the system prohibits some functionality.\n\
40*0d6140beSAndroid Build Coastguard Worker |-\n\
41*0d6140beSAndroid Build Coastguard Worker |{{Dep}}\n\
42*0d6140beSAndroid Build Coastguard Worker | '''Configuration-dependent'''. The feature was tested and should work in general but there are common \
43*0d6140beSAndroid Build Coastguard Worker configurations that drastically limit flashrom's capabilities or make it completely stop working.\n\
44*0d6140beSAndroid Build Coastguard Worker |-\n\
45*0d6140beSAndroid Build Coastguard Worker |{{?3}}\n\
46*0d6140beSAndroid Build Coastguard Worker | The feature is '''untested''' but believed to be working.\n\
47*0d6140beSAndroid Build Coastguard Worker |-\n\
48*0d6140beSAndroid Build Coastguard Worker |{{NA}}\n\
49*0d6140beSAndroid Build Coastguard Worker | The feature is '''not applicable''' in this configuration (e.g. write operations on ROM chips).\n\
50*0d6140beSAndroid Build Coastguard Worker |-\n\
51*0d6140beSAndroid Build Coastguard Worker |{{No}}\n\
52*0d6140beSAndroid Build Coastguard Worker | The feature is '''known to not work'''. Don't bother testing (nor reporting. Patches welcome! ;).\n\
53*0d6140beSAndroid Build Coastguard Worker |}\n\
54*0d6140beSAndroid Build Coastguard Worker </small></div>\n";
55*0d6140beSAndroid Build Coastguard Worker
56*0d6140beSAndroid Build Coastguard Worker static const char th_start[] = "| valign=\"top\"|\n\n\
57*0d6140beSAndroid Build Coastguard Worker {| border=\"0\" style=\"font-size: smaller\" valign=\"top\"\n\
58*0d6140beSAndroid Build Coastguard Worker |- bgcolor=\"#6699dd\"\n";
59*0d6140beSAndroid Build Coastguard Worker
60*0d6140beSAndroid Build Coastguard Worker #if CONFIG_INTERNAL == 1
61*0d6140beSAndroid Build Coastguard Worker static const char chipset_th[] = "\
62*0d6140beSAndroid Build Coastguard Worker ! align=\"left\" | Vendor\n\
63*0d6140beSAndroid Build Coastguard Worker ! align=\"left\" | Southbridge\n\
64*0d6140beSAndroid Build Coastguard Worker ! align=\"center\" | PCI IDs\n\
65*0d6140beSAndroid Build Coastguard Worker ! align=\"center\" | Status\n\n";
66*0d6140beSAndroid Build Coastguard Worker
67*0d6140beSAndroid Build Coastguard Worker static const char board_th[] = "\
68*0d6140beSAndroid Build Coastguard Worker ! align=\"left\" | Vendor\n\
69*0d6140beSAndroid Build Coastguard Worker ! align=\"left\" | Mainboard\n\
70*0d6140beSAndroid Build Coastguard Worker ! align=\"left\" | Required option\n\
71*0d6140beSAndroid Build Coastguard Worker ! align=\"center\" | Status\n\n";
72*0d6140beSAndroid Build Coastguard Worker
73*0d6140beSAndroid Build Coastguard Worker static const char board_intro[] = "\
74*0d6140beSAndroid Build Coastguard Worker \n== Supported mainboards ==\n\n\
75*0d6140beSAndroid Build Coastguard Worker In general, it is very likely that flashrom works out of the box even if your \
76*0d6140beSAndroid Build Coastguard Worker mainboard is not listed below.\n\nThis is a list of mainboards where we have \
77*0d6140beSAndroid Build Coastguard Worker verified that they either do or do not need any special initialization to \
78*0d6140beSAndroid Build Coastguard Worker make flashrom work (given flashrom supports the respective chipset and flash \
79*0d6140beSAndroid Build Coastguard Worker chip), or that they do not yet work at all. If they do not work, support may \
80*0d6140beSAndroid Build Coastguard Worker or may not be added later.\n\n\
81*0d6140beSAndroid Build Coastguard Worker Mainboards (or individual revisions) which don't appear in the list may or may \
82*0d6140beSAndroid Build Coastguard Worker not work (we don't know, someone has to give it a try). Please report any \
83*0d6140beSAndroid Build Coastguard Worker further verified mainboards on the [[Contact#Mailing_List|mailing list]].\n";
84*0d6140beSAndroid Build Coastguard Worker #endif
85*0d6140beSAndroid Build Coastguard Worker
86*0d6140beSAndroid Build Coastguard Worker static const char chip_th[] = "\
87*0d6140beSAndroid Build Coastguard Worker ! align=\"left\" | Vendor\n\
88*0d6140beSAndroid Build Coastguard Worker ! align=\"left\" | Device\n\
89*0d6140beSAndroid Build Coastguard Worker ! align=\"center\" | Size [kB]\n\
90*0d6140beSAndroid Build Coastguard Worker ! align=\"center\" | Type\n\
91*0d6140beSAndroid Build Coastguard Worker ! align=\"center\" colspan=\"4\" | Status\n\
92*0d6140beSAndroid Build Coastguard Worker ! align=\"center\" colspan=\"2\" | Voltage [V]\n\n\
93*0d6140beSAndroid Build Coastguard Worker |- bgcolor=\"#6699ff\"\n| colspan=\"4\" | \n\
94*0d6140beSAndroid Build Coastguard Worker | Probe\n| Read\n| Erase\n| Write\n\
95*0d6140beSAndroid Build Coastguard Worker | align=\"center\" | Min\n| align=\"center\" | Max\n\n";
96*0d6140beSAndroid Build Coastguard Worker
97*0d6140beSAndroid Build Coastguard Worker static const char chip_intro[] = "\
98*0d6140beSAndroid Build Coastguard Worker \n== Supported flash chips ==\n\n\
99*0d6140beSAndroid Build Coastguard Worker The list below contains all chips that have some kind of explicit support added to flashrom and their last \
100*0d6140beSAndroid Build Coastguard Worker known test status. Newer SPI flash chips might work even without explicit support if they implement SFDP ([\
101*0d6140beSAndroid Build Coastguard Worker http://www.jedec.org/standards-documents/docs/jesd216 Serial Flash Discoverable Parameters - JESD216]). \
102*0d6140beSAndroid Build Coastguard Worker Flashrom will detect this automatically and inform you about it.\n\n\
103*0d6140beSAndroid Build Coastguard Worker The names used below are designed to be as concise as possible and hence contain only the characters \
104*0d6140beSAndroid Build Coastguard Worker describing properties that are relevant to flashrom. Irrelevant characters specify attributes flashrom can not \
105*0d6140beSAndroid Build Coastguard Worker use or even detect by itself (e.g. the physical package) and have no effect on flashrom's operation. They are \
106*0d6140beSAndroid Build Coastguard Worker replaced by dots ('.') functioning as wildcards (like in Regular Expressions) or are completely omitted at the \
107*0d6140beSAndroid Build Coastguard Worker end of a name.\n";
108*0d6140beSAndroid Build Coastguard Worker
109*0d6140beSAndroid Build Coastguard Worker static const char programmer_th[] = "\
110*0d6140beSAndroid Build Coastguard Worker ! align=\"left\" | Programmer\n\
111*0d6140beSAndroid Build Coastguard Worker ! align=\"left\" | Vendor\n\
112*0d6140beSAndroid Build Coastguard Worker ! align=\"left\" | Device\n\
113*0d6140beSAndroid Build Coastguard Worker ! align=\"center\" | IDs\n\
114*0d6140beSAndroid Build Coastguard Worker ! align=\"center\" | Status\n\n";
115*0d6140beSAndroid Build Coastguard Worker
116*0d6140beSAndroid Build Coastguard Worker /* The output of this module relies on MediaWiki templates to select special formatting styles for table cells
117*0d6140beSAndroid Build Coastguard Worker * reflecting the test status of the respective hardware. This functions returns the correct template name for
118*0d6140beSAndroid Build Coastguard Worker * the supplied enum test_state. */
test_state_to_template(enum test_state test_state)119*0d6140beSAndroid Build Coastguard Worker static const char *test_state_to_template(enum test_state test_state)
120*0d6140beSAndroid Build Coastguard Worker {
121*0d6140beSAndroid Build Coastguard Worker switch (test_state) {
122*0d6140beSAndroid Build Coastguard Worker case OK: return "OK";
123*0d6140beSAndroid Build Coastguard Worker case BAD: return "No";
124*0d6140beSAndroid Build Coastguard Worker case NA: return "NA";
125*0d6140beSAndroid Build Coastguard Worker case DEP: return "Dep";
126*0d6140beSAndroid Build Coastguard Worker case NT:
127*0d6140beSAndroid Build Coastguard Worker default: return "?3";
128*0d6140beSAndroid Build Coastguard Worker }
129*0d6140beSAndroid Build Coastguard Worker }
130*0d6140beSAndroid Build Coastguard Worker
131*0d6140beSAndroid Build Coastguard Worker #if CONFIG_INTERNAL == 1
132*0d6140beSAndroid Build Coastguard Worker static const char laptop_intro[] = "\n== Supported mobile devices (laptops, tablets etc.) ==\n\n\
133*0d6140beSAndroid Build Coastguard Worker In general, flashing mobile devices is more difficult because they\n\n\
134*0d6140beSAndroid Build Coastguard Worker * often use the flash chip for stuff besides the BIOS,\n\
135*0d6140beSAndroid Build Coastguard Worker * often have special protection stuff which has to be handled by flashrom,\n\
136*0d6140beSAndroid Build Coastguard Worker * often use flash translation circuits which need drivers in flashrom.\n\n\
137*0d6140beSAndroid Build Coastguard Worker <div style=\"margin-top:0.5em; padding:0.5em 0.5em 0.5em 0.5em; \
138*0d6140beSAndroid Build Coastguard Worker background-color:#ff6666; align:right; border:1px solid #000000;\">\n\
139*0d6140beSAndroid Build Coastguard Worker '''IMPORTANT:''' At this point we recommend to '''not''' use flashrom on \
140*0d6140beSAndroid Build Coastguard Worker untested mobile devices unless you have a means to recover from a flashing that goes \
141*0d6140beSAndroid Build Coastguard Worker wrong (a working backup flash chip and/or good soldering skills).\n</div>\n";
142*0d6140beSAndroid Build Coastguard Worker
print_supported_chipsets_wiki(int cols)143*0d6140beSAndroid Build Coastguard Worker static void print_supported_chipsets_wiki(int cols)
144*0d6140beSAndroid Build Coastguard Worker {
145*0d6140beSAndroid Build Coastguard Worker int i;
146*0d6140beSAndroid Build Coastguard Worker unsigned int lines_per_col;
147*0d6140beSAndroid Build Coastguard Worker const struct penable *e;
148*0d6140beSAndroid Build Coastguard Worker int enablescount = 0, color = 1;
149*0d6140beSAndroid Build Coastguard Worker
150*0d6140beSAndroid Build Coastguard Worker for (e = chipset_enables; e->vendor_name != NULL; e++)
151*0d6140beSAndroid Build Coastguard Worker enablescount++;
152*0d6140beSAndroid Build Coastguard Worker
153*0d6140beSAndroid Build Coastguard Worker /* +1 to force the resulting number of columns to be < cols */
154*0d6140beSAndroid Build Coastguard Worker lines_per_col = enablescount / cols + ((enablescount%cols) > 0 ? 1 : 0);
155*0d6140beSAndroid Build Coastguard Worker
156*0d6140beSAndroid Build Coastguard Worker printf("\n== Supported chipsets ==\n\nTotal amount of supported chipsets: '''%d'''\n\n"
157*0d6140beSAndroid Build Coastguard Worker "{| border=\"0\" valign=\"top\"\n", enablescount);
158*0d6140beSAndroid Build Coastguard Worker
159*0d6140beSAndroid Build Coastguard Worker e = chipset_enables;
160*0d6140beSAndroid Build Coastguard Worker for (i = 0; e[i].vendor_name != NULL; i++) {
161*0d6140beSAndroid Build Coastguard Worker if ((i % lines_per_col) == 0)
162*0d6140beSAndroid Build Coastguard Worker printf("%s%s", th_start, chipset_th);
163*0d6140beSAndroid Build Coastguard Worker
164*0d6140beSAndroid Build Coastguard Worker /* Alternate colors if the vendor changes. */
165*0d6140beSAndroid Build Coastguard Worker if (i > 0 && strcmp(e[i].vendor_name, e[i - 1].vendor_name))
166*0d6140beSAndroid Build Coastguard Worker color = !color;
167*0d6140beSAndroid Build Coastguard Worker
168*0d6140beSAndroid Build Coastguard Worker printf("|- bgcolor=\"#%s\"\n| %s || %s "
169*0d6140beSAndroid Build Coastguard Worker "|| %04x:%04x || {{%s}}\n", (color) ? "eeeeee" : "dddddd",
170*0d6140beSAndroid Build Coastguard Worker e[i].vendor_name, e[i].device_name,
171*0d6140beSAndroid Build Coastguard Worker e[i].vendor_id, e[i].device_id,
172*0d6140beSAndroid Build Coastguard Worker test_state_to_template(e[i].status));
173*0d6140beSAndroid Build Coastguard Worker
174*0d6140beSAndroid Build Coastguard Worker if (((i % lines_per_col) + 1) == lines_per_col)
175*0d6140beSAndroid Build Coastguard Worker printf("\n|}\n\n");
176*0d6140beSAndroid Build Coastguard Worker }
177*0d6140beSAndroid Build Coastguard Worker
178*0d6140beSAndroid Build Coastguard Worker /* end inner table if it did not fill the last column fully */
179*0d6140beSAndroid Build Coastguard Worker if (((i % lines_per_col)) > 0)
180*0d6140beSAndroid Build Coastguard Worker printf("\n|}\n\n");
181*0d6140beSAndroid Build Coastguard Worker printf("\n\n|}\n");
182*0d6140beSAndroid Build Coastguard Worker }
183*0d6140beSAndroid Build Coastguard Worker
print_supported_boards_wiki_helper(const char * devicetype,int cols,const struct board_info boards[])184*0d6140beSAndroid Build Coastguard Worker static void print_supported_boards_wiki_helper(const char *devicetype, int cols, const struct board_info boards[])
185*0d6140beSAndroid Build Coastguard Worker {
186*0d6140beSAndroid Build Coastguard Worker int i, k;
187*0d6140beSAndroid Build Coastguard Worker unsigned int boardcount, lines_per_col;
188*0d6140beSAndroid Build Coastguard Worker unsigned int boardcount_good = 0, boardcount_bad = 0, boardcount_nt = 0;
189*0d6140beSAndroid Build Coastguard Worker int num_notes = 0, color = 1;
190*0d6140beSAndroid Build Coastguard Worker char *notes = calloc(1, 1);
191*0d6140beSAndroid Build Coastguard Worker char tmp[900 + 1];
192*0d6140beSAndroid Build Coastguard Worker const struct board_match *b = board_matches;
193*0d6140beSAndroid Build Coastguard Worker
194*0d6140beSAndroid Build Coastguard Worker for (i = 0; boards[i].vendor != NULL; i++) {
195*0d6140beSAndroid Build Coastguard Worker if (boards[i].working == OK)
196*0d6140beSAndroid Build Coastguard Worker boardcount_good++;
197*0d6140beSAndroid Build Coastguard Worker else if (boards[i].working == NT)
198*0d6140beSAndroid Build Coastguard Worker boardcount_nt++;
199*0d6140beSAndroid Build Coastguard Worker else
200*0d6140beSAndroid Build Coastguard Worker boardcount_bad++;
201*0d6140beSAndroid Build Coastguard Worker }
202*0d6140beSAndroid Build Coastguard Worker boardcount = boardcount_good + boardcount_nt + boardcount_bad;
203*0d6140beSAndroid Build Coastguard Worker
204*0d6140beSAndroid Build Coastguard Worker /* +1 to force the resulting number of columns to be < cols */
205*0d6140beSAndroid Build Coastguard Worker lines_per_col = boardcount / cols + ((boardcount%cols) > 0 ? 1 : 0);
206*0d6140beSAndroid Build Coastguard Worker
207*0d6140beSAndroid Build Coastguard Worker printf("\n\nTotal amount of known good %s: '''%d'''; "
208*0d6140beSAndroid Build Coastguard Worker "Untested (e.g. user vanished before testing new code): '''%d'''; "
209*0d6140beSAndroid Build Coastguard Worker "Not yet supported (i.e. known-bad): '''%d'''.\n\n"
210*0d6140beSAndroid Build Coastguard Worker "{| border=\"0\" valign=\"top\"\n", devicetype, boardcount_good, boardcount_nt, boardcount_bad);
211*0d6140beSAndroid Build Coastguard Worker
212*0d6140beSAndroid Build Coastguard Worker for (i = 0; boards[i].vendor != NULL; i++) {
213*0d6140beSAndroid Build Coastguard Worker if ((i % lines_per_col) == 0)
214*0d6140beSAndroid Build Coastguard Worker printf("%s%s", th_start, board_th);
215*0d6140beSAndroid Build Coastguard Worker
216*0d6140beSAndroid Build Coastguard Worker /* Alternate colors if the vendor changes. */
217*0d6140beSAndroid Build Coastguard Worker if (i > 0 && strcmp(boards[i].vendor, boards[i - 1].vendor))
218*0d6140beSAndroid Build Coastguard Worker color = !color;
219*0d6140beSAndroid Build Coastguard Worker
220*0d6140beSAndroid Build Coastguard Worker k = 0;
221*0d6140beSAndroid Build Coastguard Worker while ((b[k].vendor_name != NULL) &&
222*0d6140beSAndroid Build Coastguard Worker (strcmp(b[k].vendor_name, boards[i].vendor) ||
223*0d6140beSAndroid Build Coastguard Worker strcmp(b[k].board_name, boards[i].name))) {
224*0d6140beSAndroid Build Coastguard Worker k++;
225*0d6140beSAndroid Build Coastguard Worker }
226*0d6140beSAndroid Build Coastguard Worker
227*0d6140beSAndroid Build Coastguard Worker printf("|- bgcolor=\"#%s\"\n| %s || %s%s %s%s || %s%s%s%s "
228*0d6140beSAndroid Build Coastguard Worker "|| {{%s}}", (color) ? "eeeeee" : "dddddd",
229*0d6140beSAndroid Build Coastguard Worker boards[i].vendor,
230*0d6140beSAndroid Build Coastguard Worker boards[i].url ? "[" : "",
231*0d6140beSAndroid Build Coastguard Worker boards[i].url ? boards[i].url : "",
232*0d6140beSAndroid Build Coastguard Worker boards[i].name,
233*0d6140beSAndroid Build Coastguard Worker boards[i].url ? "]" : "",
234*0d6140beSAndroid Build Coastguard Worker b[k].lb_vendor ? "-p internal:mainboard=" : "—",
235*0d6140beSAndroid Build Coastguard Worker b[k].lb_vendor ? b[k].lb_vendor : "",
236*0d6140beSAndroid Build Coastguard Worker b[k].lb_vendor ? ":" : "",
237*0d6140beSAndroid Build Coastguard Worker b[k].lb_vendor ? b[k].lb_part : "",
238*0d6140beSAndroid Build Coastguard Worker test_state_to_template(boards[i].working));
239*0d6140beSAndroid Build Coastguard Worker
240*0d6140beSAndroid Build Coastguard Worker if (boards[i].note) {
241*0d6140beSAndroid Build Coastguard Worker num_notes++;
242*0d6140beSAndroid Build Coastguard Worker printf(" <span id=\"%s_ref%d\"><sup>[[#%s_note%d|%d]]</sup></span>\n",
243*0d6140beSAndroid Build Coastguard Worker devicetype, num_notes, devicetype, num_notes, num_notes);
244*0d6140beSAndroid Build Coastguard Worker int ret = snprintf(tmp, sizeof(tmp),
245*0d6140beSAndroid Build Coastguard Worker "<span id=\"%s_note%d\">%d. [[#%s_ref%d|↑]]</span>"
246*0d6140beSAndroid Build Coastguard Worker " <nowiki>%s</nowiki><br />\n", devicetype, num_notes, num_notes,
247*0d6140beSAndroid Build Coastguard Worker devicetype, num_notes, boards[i].note);
248*0d6140beSAndroid Build Coastguard Worker if (ret < 0 || (unsigned int)ret >= sizeof(tmp)) {
249*0d6140beSAndroid Build Coastguard Worker fprintf(stderr, "Footnote text #%d of %s truncated (ret=%d, sizeof(tmp)=%zu)\n",
250*0d6140beSAndroid Build Coastguard Worker num_notes, devicetype, ret, sizeof(tmp));
251*0d6140beSAndroid Build Coastguard Worker }
252*0d6140beSAndroid Build Coastguard Worker notes = strcat_realloc(notes, tmp);
253*0d6140beSAndroid Build Coastguard Worker } else {
254*0d6140beSAndroid Build Coastguard Worker printf("\n");
255*0d6140beSAndroid Build Coastguard Worker }
256*0d6140beSAndroid Build Coastguard Worker
257*0d6140beSAndroid Build Coastguard Worker if (((i % lines_per_col) + 1) == lines_per_col)
258*0d6140beSAndroid Build Coastguard Worker printf("\n|}\n\n");
259*0d6140beSAndroid Build Coastguard Worker }
260*0d6140beSAndroid Build Coastguard Worker
261*0d6140beSAndroid Build Coastguard Worker /* end inner table if it did not fill the last column fully */
262*0d6140beSAndroid Build Coastguard Worker if (((i % lines_per_col)) > 0)
263*0d6140beSAndroid Build Coastguard Worker printf("\n|}\n\n");
264*0d6140beSAndroid Build Coastguard Worker printf("|}\n");
265*0d6140beSAndroid Build Coastguard Worker
266*0d6140beSAndroid Build Coastguard Worker if (num_notes > 0)
267*0d6140beSAndroid Build Coastguard Worker printf("\n<small>\n%s</small>\n", notes);
268*0d6140beSAndroid Build Coastguard Worker free(notes);
269*0d6140beSAndroid Build Coastguard Worker }
270*0d6140beSAndroid Build Coastguard Worker
print_supported_boards_wiki(void)271*0d6140beSAndroid Build Coastguard Worker static void print_supported_boards_wiki(void)
272*0d6140beSAndroid Build Coastguard Worker {
273*0d6140beSAndroid Build Coastguard Worker printf("%s", board_intro);
274*0d6140beSAndroid Build Coastguard Worker print_supported_boards_wiki_helper("mainboards", 2, boards_known);
275*0d6140beSAndroid Build Coastguard Worker
276*0d6140beSAndroid Build Coastguard Worker printf("%s", laptop_intro);
277*0d6140beSAndroid Build Coastguard Worker print_supported_boards_wiki_helper("mobile devices", 1, laptops_known);
278*0d6140beSAndroid Build Coastguard Worker }
279*0d6140beSAndroid Build Coastguard Worker #endif
280*0d6140beSAndroid Build Coastguard Worker
print_supported_chips_wiki(int cols)281*0d6140beSAndroid Build Coastguard Worker static void print_supported_chips_wiki(int cols)
282*0d6140beSAndroid Build Coastguard Worker {
283*0d6140beSAndroid Build Coastguard Worker unsigned int lines_per_col;
284*0d6140beSAndroid Build Coastguard Worker char *s;
285*0d6140beSAndroid Build Coastguard Worker char vmax[6];
286*0d6140beSAndroid Build Coastguard Worker char vmin[6];
287*0d6140beSAndroid Build Coastguard Worker const struct flashchip *f, *old = NULL;
288*0d6140beSAndroid Build Coastguard Worker int i = 0, c = 1, chipcount = 0;
289*0d6140beSAndroid Build Coastguard Worker
290*0d6140beSAndroid Build Coastguard Worker for (f = flashchips; f->name != NULL; f++) {
291*0d6140beSAndroid Build Coastguard Worker /* Don't count generic entries. */
292*0d6140beSAndroid Build Coastguard Worker if (!strncmp(f->vendor, "Unknown", 7) ||
293*0d6140beSAndroid Build Coastguard Worker !strncmp(f->vendor, "Programmer", 10) ||
294*0d6140beSAndroid Build Coastguard Worker !strncmp(f->name, "unknown", 7))
295*0d6140beSAndroid Build Coastguard Worker continue;
296*0d6140beSAndroid Build Coastguard Worker chipcount++;
297*0d6140beSAndroid Build Coastguard Worker }
298*0d6140beSAndroid Build Coastguard Worker
299*0d6140beSAndroid Build Coastguard Worker /* +1 to force the resulting number of columns to be < cols */
300*0d6140beSAndroid Build Coastguard Worker lines_per_col = chipcount / cols + ((chipcount%cols) > 0 ? 1 : 0);
301*0d6140beSAndroid Build Coastguard Worker
302*0d6140beSAndroid Build Coastguard Worker printf("%s", chip_intro);
303*0d6140beSAndroid Build Coastguard Worker printf("\nTotal amount of supported chips: '''%d'''\n\n"
304*0d6140beSAndroid Build Coastguard Worker "{| border=\"0\" valign=\"top\"\n", chipcount);
305*0d6140beSAndroid Build Coastguard Worker
306*0d6140beSAndroid Build Coastguard Worker for (f = flashchips; f->name != NULL; f++) {
307*0d6140beSAndroid Build Coastguard Worker /* Don't print generic entries. */
308*0d6140beSAndroid Build Coastguard Worker if (!strncmp(f->vendor, "Unknown", 7) ||
309*0d6140beSAndroid Build Coastguard Worker !strncmp(f->vendor, "Programmer", 10) ||
310*0d6140beSAndroid Build Coastguard Worker !strncmp(f->name, "unknown", 7))
311*0d6140beSAndroid Build Coastguard Worker continue;
312*0d6140beSAndroid Build Coastguard Worker
313*0d6140beSAndroid Build Coastguard Worker if ((i % lines_per_col) == 0)
314*0d6140beSAndroid Build Coastguard Worker printf("%s%s", th_start, chip_th);
315*0d6140beSAndroid Build Coastguard Worker
316*0d6140beSAndroid Build Coastguard Worker /* Alternate colors if the vendor changes. */
317*0d6140beSAndroid Build Coastguard Worker if (old != NULL && strcmp(old->vendor, f->vendor))
318*0d6140beSAndroid Build Coastguard Worker c = !c;
319*0d6140beSAndroid Build Coastguard Worker
320*0d6140beSAndroid Build Coastguard Worker old = f;
321*0d6140beSAndroid Build Coastguard Worker s = flashbuses_to_text(f->bustype);
322*0d6140beSAndroid Build Coastguard Worker sprintf(vmin, "%0.03f", f->voltage.min / (double)1000);
323*0d6140beSAndroid Build Coastguard Worker sprintf(vmax, "%0.03f", f->voltage.max / (double)1000);
324*0d6140beSAndroid Build Coastguard Worker printf("|- bgcolor=\"#%s\"\n| %s || %s || align=\"right\" | %d "
325*0d6140beSAndroid Build Coastguard Worker "|| %s || {{%s}} || {{%s}} || {{%s}} || {{%s}}"
326*0d6140beSAndroid Build Coastguard Worker "|| %s || %s\n",
327*0d6140beSAndroid Build Coastguard Worker (c == 1) ? "eeeeee" : "dddddd", f->vendor, f->name,
328*0d6140beSAndroid Build Coastguard Worker f->total_size, s ? s : "?",
329*0d6140beSAndroid Build Coastguard Worker test_state_to_template(f->tested.probe),
330*0d6140beSAndroid Build Coastguard Worker test_state_to_template(f->tested.read),
331*0d6140beSAndroid Build Coastguard Worker test_state_to_template(f->tested.erase),
332*0d6140beSAndroid Build Coastguard Worker test_state_to_template(f->tested.write),
333*0d6140beSAndroid Build Coastguard Worker f->voltage.min ? vmin : "?",
334*0d6140beSAndroid Build Coastguard Worker f->voltage.max ? vmax : "?");
335*0d6140beSAndroid Build Coastguard Worker free(s);
336*0d6140beSAndroid Build Coastguard Worker
337*0d6140beSAndroid Build Coastguard Worker if (((i % lines_per_col) + 1) == lines_per_col)
338*0d6140beSAndroid Build Coastguard Worker printf("\n|}\n\n");
339*0d6140beSAndroid Build Coastguard Worker i++;
340*0d6140beSAndroid Build Coastguard Worker }
341*0d6140beSAndroid Build Coastguard Worker /* end inner table if it did not fill the last column fully */
342*0d6140beSAndroid Build Coastguard Worker if (((i % lines_per_col)) > 0)
343*0d6140beSAndroid Build Coastguard Worker printf("\n|}\n\n");
344*0d6140beSAndroid Build Coastguard Worker printf("|}\n\n");
345*0d6140beSAndroid Build Coastguard Worker }
346*0d6140beSAndroid Build Coastguard Worker
347*0d6140beSAndroid Build Coastguard Worker /* Following functions are not needed when no PCI/USB programmers are compiled in,
348*0d6140beSAndroid Build Coastguard Worker * but since print_wiki code has no size constraints we include it unconditionally. */
count_supported_devs_wiki(const struct dev_entry * devs)349*0d6140beSAndroid Build Coastguard Worker static int count_supported_devs_wiki(const struct dev_entry *devs)
350*0d6140beSAndroid Build Coastguard Worker {
351*0d6140beSAndroid Build Coastguard Worker unsigned int count = 0;
352*0d6140beSAndroid Build Coastguard Worker unsigned int i = 0;
353*0d6140beSAndroid Build Coastguard Worker for (i = 0; devs[i].vendor_id != 0; i++)
354*0d6140beSAndroid Build Coastguard Worker count++;
355*0d6140beSAndroid Build Coastguard Worker return count;
356*0d6140beSAndroid Build Coastguard Worker }
357*0d6140beSAndroid Build Coastguard Worker
print_supported_devs_wiki_helper(const struct programmer_entry * const prog)358*0d6140beSAndroid Build Coastguard Worker static void print_supported_devs_wiki_helper(const struct programmer_entry *const prog)
359*0d6140beSAndroid Build Coastguard Worker {
360*0d6140beSAndroid Build Coastguard Worker int i = 0;
361*0d6140beSAndroid Build Coastguard Worker static int c = 0;
362*0d6140beSAndroid Build Coastguard Worker const struct dev_entry *devs = prog->devs.dev;
363*0d6140beSAndroid Build Coastguard Worker const unsigned int count = count_supported_devs_wiki(devs);
364*0d6140beSAndroid Build Coastguard Worker
365*0d6140beSAndroid Build Coastguard Worker /* Alternate colors if the vendor changes. */
366*0d6140beSAndroid Build Coastguard Worker c = !c;
367*0d6140beSAndroid Build Coastguard Worker
368*0d6140beSAndroid Build Coastguard Worker for (i = 0; devs[i].vendor_id != 0; i++) {
369*0d6140beSAndroid Build Coastguard Worker printf("|- bgcolor=\"#%s\"\n", (c) ? "eeeeee" : "dddddd");
370*0d6140beSAndroid Build Coastguard Worker if (i == 0)
371*0d6140beSAndroid Build Coastguard Worker printf("| rowspan=\"%u\" | %s |", count, prog->name);
372*0d6140beSAndroid Build Coastguard Worker printf("| %s || %s || %04x:%04x || {{%s}}\n", devs[i].vendor_name, devs[i].device_name,
373*0d6140beSAndroid Build Coastguard Worker devs[i].vendor_id, devs[i].device_id, test_state_to_template(devs[i].status));
374*0d6140beSAndroid Build Coastguard Worker }
375*0d6140beSAndroid Build Coastguard Worker }
376*0d6140beSAndroid Build Coastguard Worker
print_supported_devs_wiki()377*0d6140beSAndroid Build Coastguard Worker static void print_supported_devs_wiki()
378*0d6140beSAndroid Build Coastguard Worker {
379*0d6140beSAndroid Build Coastguard Worker unsigned int pci_count = 0;
380*0d6140beSAndroid Build Coastguard Worker unsigned int usb_count = 0;
381*0d6140beSAndroid Build Coastguard Worker unsigned int i;
382*0d6140beSAndroid Build Coastguard Worker
383*0d6140beSAndroid Build Coastguard Worker for (i = 0; i < programmer_table_size; i++) {
384*0d6140beSAndroid Build Coastguard Worker const struct programmer_entry *const prog = programmer_table[i];
385*0d6140beSAndroid Build Coastguard Worker switch (prog->type) {
386*0d6140beSAndroid Build Coastguard Worker case USB:
387*0d6140beSAndroid Build Coastguard Worker usb_count += count_supported_devs_wiki(prog->devs.dev);
388*0d6140beSAndroid Build Coastguard Worker break;
389*0d6140beSAndroid Build Coastguard Worker case PCI:
390*0d6140beSAndroid Build Coastguard Worker pci_count += count_supported_devs_wiki(prog->devs.dev);
391*0d6140beSAndroid Build Coastguard Worker break;
392*0d6140beSAndroid Build Coastguard Worker case OTHER:
393*0d6140beSAndroid Build Coastguard Worker default:
394*0d6140beSAndroid Build Coastguard Worker break;
395*0d6140beSAndroid Build Coastguard Worker }
396*0d6140beSAndroid Build Coastguard Worker }
397*0d6140beSAndroid Build Coastguard Worker
398*0d6140beSAndroid Build Coastguard Worker printf("\n== PCI Devices ==\n\n"
399*0d6140beSAndroid Build Coastguard Worker "Total amount of supported PCI devices flashrom can use as a programmer: '''%d'''\n\n"
400*0d6140beSAndroid Build Coastguard Worker "{%s%s", pci_count, th_start, programmer_th);
401*0d6140beSAndroid Build Coastguard Worker
402*0d6140beSAndroid Build Coastguard Worker for (i = 0; i < programmer_table_size; i++) {
403*0d6140beSAndroid Build Coastguard Worker const struct programmer_entry *const prog = programmer_table[i];
404*0d6140beSAndroid Build Coastguard Worker if (prog->type == PCI) {
405*0d6140beSAndroid Build Coastguard Worker print_supported_devs_wiki_helper(prog);
406*0d6140beSAndroid Build Coastguard Worker }
407*0d6140beSAndroid Build Coastguard Worker }
408*0d6140beSAndroid Build Coastguard Worker printf("\n|}\n\n|}\n");
409*0d6140beSAndroid Build Coastguard Worker
410*0d6140beSAndroid Build Coastguard Worker printf("\n== USB Devices ==\n\n"
411*0d6140beSAndroid Build Coastguard Worker "Total amount of supported USB devices flashrom can use as a programmer: '''%d'''\n\n"
412*0d6140beSAndroid Build Coastguard Worker "{%s%s", usb_count, th_start, programmer_th);
413*0d6140beSAndroid Build Coastguard Worker
414*0d6140beSAndroid Build Coastguard Worker for (i = 0; i < programmer_table_size; i++) {
415*0d6140beSAndroid Build Coastguard Worker const struct programmer_entry *const prog = programmer_table[i];
416*0d6140beSAndroid Build Coastguard Worker if (prog->type == USB) {
417*0d6140beSAndroid Build Coastguard Worker print_supported_devs_wiki_helper(prog);
418*0d6140beSAndroid Build Coastguard Worker }
419*0d6140beSAndroid Build Coastguard Worker }
420*0d6140beSAndroid Build Coastguard Worker printf("\n|}\n\n|}\n");
421*0d6140beSAndroid Build Coastguard Worker
422*0d6140beSAndroid Build Coastguard Worker printf("\n== Other programmers ==\n\n"
423*0d6140beSAndroid Build Coastguard Worker "{%s", th_start);
424*0d6140beSAndroid Build Coastguard Worker printf("! align=\"left\" | Programmer\n"
425*0d6140beSAndroid Build Coastguard Worker "! align=\"left\" | Note\n\n");
426*0d6140beSAndroid Build Coastguard Worker
427*0d6140beSAndroid Build Coastguard Worker for (i = 0; i < programmer_table_size; i++) {
428*0d6140beSAndroid Build Coastguard Worker static int c = 0;
429*0d6140beSAndroid Build Coastguard Worker const struct programmer_entry *const prog = programmer_table[i];
430*0d6140beSAndroid Build Coastguard Worker if (prog->type == OTHER && prog->devs.note != NULL) {
431*0d6140beSAndroid Build Coastguard Worker c = !c;
432*0d6140beSAndroid Build Coastguard Worker printf("|- bgcolor=\"#%s\"\n", (c) ? "eeeeee" : "dddddd");
433*0d6140beSAndroid Build Coastguard Worker printf("| %s || %s", prog->name, prog->devs.note);
434*0d6140beSAndroid Build Coastguard Worker }
435*0d6140beSAndroid Build Coastguard Worker }
436*0d6140beSAndroid Build Coastguard Worker printf("\n|}\n\n|}\n");
437*0d6140beSAndroid Build Coastguard Worker }
438*0d6140beSAndroid Build Coastguard Worker
print_supported_wiki(void)439*0d6140beSAndroid Build Coastguard Worker void print_supported_wiki(void)
440*0d6140beSAndroid Build Coastguard Worker {
441*0d6140beSAndroid Build Coastguard Worker time_t t = time(NULL);
442*0d6140beSAndroid Build Coastguard Worker char buf[sizeof("1986-02-28T12:37:42Z")];
443*0d6140beSAndroid Build Coastguard Worker strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ", gmtime(&t));
444*0d6140beSAndroid Build Coastguard Worker
445*0d6140beSAndroid Build Coastguard Worker printf(wiki_header, buf, flashrom_version);
446*0d6140beSAndroid Build Coastguard Worker print_supported_chips_wiki(2);
447*0d6140beSAndroid Build Coastguard Worker #if CONFIG_INTERNAL == 1
448*0d6140beSAndroid Build Coastguard Worker print_supported_chipsets_wiki(3);
449*0d6140beSAndroid Build Coastguard Worker print_supported_boards_wiki();
450*0d6140beSAndroid Build Coastguard Worker #endif
451*0d6140beSAndroid Build Coastguard Worker print_supported_devs_wiki();
452*0d6140beSAndroid Build Coastguard Worker }
453