print_wiki.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /*
  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
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <stdlib.h>
  24. #include <time.h>
  25. #include "flash.h"
  26. #include "flashchips.h"
  27. #include "programmer.h"
  28. static const char wiki_header[] = "= Supported devices =\n\n\
  29. <div style=\"margin-top:0.5em; padding:0.5em 0.5em 0.5em 0.5em; \
  30. background-color:#eeeeee; text-align:right; border:1px solid #aabbcc;\">\
  31. <small>\n\
  32. Please do '''not''' edit these tables in the wiki directly, they are \
  33. generated by pasting '''flashrom -z''' output.<br />\
  34. '''Last update:''' %s(generated by flashrom %s)\n</small></div>\n";
  35. #if CONFIG_INTERNAL == 1
  36. static const char chipset_th[] = "{| border=\"0\" style=\"font-size: smaller\"\n\
  37. |- bgcolor=\"#6699dd\"\n! align=\"left\" | Vendor\n\
  38. ! align=\"left\" | Southbridge\n! align=\"center\" | PCI IDs\n\
  39. ! align=\"center\" | Status\n\n";
  40. static const char board_th[] = "{| border=\"0\" style=\"font-size: smaller\" \
  41. valign=\"top\"\n|- bgcolor=\"#6699dd\"\n! align=\"left\" | Vendor\n\
  42. ! align=\"left\" | Mainboard\n! align=\"left\" | Required option\n\
  43. ! align=\"center\" | Status\n\n";
  44. static const char board_intro[] = "\
  45. \n== Supported mainboards ==\n\n\
  46. In general, it is very likely that flashrom works out of the box even if your \
  47. mainboard is not listed below.\n\nThis is a list of mainboards where we have \
  48. verified that they either do or do not need any special initialization to \
  49. make flashrom work (given flashrom supports the respective chipset and flash \
  50. chip), or that they do not yet work at all. If they do not work, support may \
  51. or may not be added later.\n\n\
  52. Mainboards (or individual revisions) which don't appear in the list may or may \
  53. not work (we don't know, someone has to give it a try). Please report any \
  54. further verified mainboards on the [[Mailinglist|mailing list]].\n";
  55. #endif
  56. static const char chip_th[] = "{\
  57. | border=\"0\" style=\"font-size: smaller\" valign=\"top\"\n\
  58. |- bgcolor=\"#6699dd\"\n\
  59. ! align=\"left\" | Vendor\n\
  60. ! align=\"left\" | Device\n\
  61. ! align=\"center\" | Size [kB]\n\
  62. ! align=\"center\" | Type\n\
  63. ! align=\"center\" colspan=\"4\" | Status\n\
  64. ! align=\"center\" colspan=\"2\" | Voltage [V]\n\n\
  65. |- bgcolor=\"#6699ff\"\n| colspan=\"4\" | &nbsp;\n\
  66. | Probe\n| Read\n| Erase\n| Write\n\
  67. | align=\"center\" | Min \n| align=\"center\" | Max\n\n";
  68. static const char programmer_section[] = "\
  69. \n== Supported programmers ==\n\nThis is a list \
  70. of supported PCI devices flashrom can use as programmer:\n\n{| border=\"0\" \
  71. valign=\"top\"\n| valign=\"top\"|\n\n{| border=\"0\" style=\"font-size: \
  72. smaller\" valign=\"top\"\n|- bgcolor=\"#6699dd\"\n! align=\"left\" | Vendor\n\
  73. ! align=\"left\" | Device\n! align=\"center\" | PCI IDs\n\
  74. ! align=\"center\" | Status\n\n";
  75. #if CONFIG_INTERNAL == 1
  76. static const char laptop_intro[] = "\n== Supported laptops/notebooks ==\n\n\
  77. In general, flashing laptops is more difficult because laptops\n\n\
  78. * often use the flash chip for stuff besides the BIOS,\n\
  79. * often have special protection stuff which has to be handled by flashrom,\n\
  80. * often use flash translation circuits which need drivers in flashrom.\n\n\
  81. <div style=\"margin-top:0.5em; padding:0.5em 0.5em 0.5em 0.5em; \
  82. background-color:#ff6666; align:right; border:1px solid #000000;\">\n\
  83. '''IMPORTANT:''' At this point we recommend to '''not''' use flashrom on \
  84. untested laptops unless you have a means to recover from a flashing that goes \
  85. wrong (a working backup flash chip and/or good soldering skills).\n</div>\n";
  86. static void print_supported_chipsets_wiki(int cols)
  87. {
  88. int i, j, enablescount = 0, color = 1;
  89. const struct penable *e;
  90. for (e = chipset_enables; e->vendor_name != NULL; e++)
  91. enablescount++;
  92. printf("\n== Supported chipsets ==\n\nTotal amount of supported "
  93. "chipsets: '''%d'''\n\n{| border=\"0\" valign=\"top\"\n| "
  94. "valign=\"top\"|\n\n%s", enablescount, chipset_th);
  95. e = chipset_enables;
  96. for (i = 0, j = 0; e[i].vendor_name != NULL; i++, j++) {
  97. /* Alternate colors if the vendor changes. */
  98. if (i > 0 && strcmp(e[i].vendor_name, e[i - 1].vendor_name))
  99. color = !color;
  100. printf("|- bgcolor=\"#%s\"\n| %s || %s "
  101. "|| %04x:%04x || %s\n", (color) ? "eeeeee" : "dddddd",
  102. e[i].vendor_name, e[i].device_name,
  103. e[i].vendor_id, e[i].device_id,
  104. (e[i].status == OK) ? "{{OK}}" : "{{?3}}");
  105. /* Split table in 'cols' columns. */
  106. if (j >= (enablescount / cols + 1)) {
  107. printf("\n|}\n\n| valign=\"top\"|\n\n%s", chipset_th);
  108. j = 0;
  109. }
  110. }
  111. printf("\n|}\n\n|}\n");
  112. }
  113. static void wiki_helper(const char *devicetype, int cols,
  114. const struct board_info boards[])
  115. {
  116. int i, j, k = 0, boardcount_good = 0, boardcount_bad = 0, color = 1;
  117. int num_notes = 0;
  118. char *notes = calloc(1, 1);
  119. char tmp[900 + 1];
  120. const struct board_match *b = board_matches;
  121. for (i = 0; boards[i].vendor != NULL; i++) {
  122. if (boards[i].working)
  123. boardcount_good++;
  124. else
  125. boardcount_bad++;
  126. }
  127. printf("\n\nTotal amount of supported %s: '''%d'''. "
  128. "Not yet supported (i.e., known-bad): '''%d'''.\n\n"
  129. "{| border=\"0\" valign=\"top\"\n| valign=\"top\"|\n\n%s",
  130. devicetype, boardcount_good, boardcount_bad, board_th);
  131. for (i = 0, j = 0; boards[i].vendor != NULL; i++, j++) {
  132. /* Alternate colors if the vendor changes. */
  133. if (i > 0 && strcmp(boards[i].vendor, boards[i - 1].vendor))
  134. color = !color;
  135. k = 0;
  136. while ((b[k].vendor_name != NULL) &&
  137. (strcmp(b[k].vendor_name, boards[i].vendor) ||
  138. strcmp(b[k].board_name, boards[i].name))) {
  139. k++;
  140. }
  141. printf("|- bgcolor=\"#%s\"\n| %s || %s%s %s%s || %s%s%s%s "
  142. "|| {{%s}}", (color) ? "eeeeee" : "dddddd",
  143. boards[i].vendor,
  144. boards[i].url ? "[" : "",
  145. boards[i].url ? boards[i].url : "",
  146. boards[i].name,
  147. boards[i].url ? "]" : "",
  148. b[k].lb_vendor ? "-p internal:mainboards=" : "&mdash;",
  149. b[k].lb_vendor ? b[k].lb_vendor : "",
  150. b[k].lb_vendor ? ":" : "",
  151. b[k].lb_vendor ? b[k].lb_part : "",
  152. (boards[i].working) ? "OK" : "No");
  153. if (boards[i].note) {
  154. printf("<sup>%d</sup>\n", num_notes + 1);
  155. snprintf(tmp, sizeof(tmp), "<sup>%d</sup> %s<br />\n",
  156. 1 + num_notes++, boards[i].note);
  157. notes = strcat_realloc(notes, tmp);
  158. } else {
  159. printf("\n");
  160. }
  161. /* Split table in 'cols' columns. */
  162. if (j >= ((boardcount_good + boardcount_bad) / cols + 1)) {
  163. printf("\n|}\n\n| valign=\"top\"|\n\n%s", board_th);
  164. j = 0;
  165. }
  166. }
  167. printf("\n|}\n\n|}\n");
  168. if (num_notes > 0)
  169. printf("\n<small>\n%s</small>\n", notes);
  170. free(notes);
  171. }
  172. static void print_supported_boards_wiki(void)
  173. {
  174. printf("%s", board_intro);
  175. wiki_helper("boards", 2, boards_known);
  176. printf("%s", laptop_intro);
  177. wiki_helper("laptops", 1, laptops_known);
  178. }
  179. #endif
  180. static void print_supported_chips_wiki(int cols)
  181. {
  182. int i = 0, c = 1, chipcount = 0;
  183. const struct flashchip *f, *old = NULL;
  184. uint32_t t;
  185. char *s;
  186. char vmax[6];
  187. char vmin[6];
  188. for (f = flashchips; f->name != NULL; f++) {
  189. /* Don't count generic entries. */
  190. if (!strncmp(f->vendor, "Unknown", 7) ||
  191. !strncmp(f->vendor, "Programmer", 10) ||
  192. !strncmp(f->name, "unknown", 7))
  193. continue;
  194. chipcount++;
  195. }
  196. printf("\n== Supported chips ==\n\nTotal amount of supported "
  197. "chips: '''%d'''\n\n{| border=\"0\" valign=\"top\"\n"
  198. "| valign=\"top\"|\n\n%s", chipcount, chip_th);
  199. for (f = flashchips; f->name != NULL; f++, i++) {
  200. /* Don't print generic entries. */
  201. if (!strncmp(f->vendor, "Unknown", 7) ||
  202. !strncmp(f->vendor, "Programmer", 10) ||
  203. !strncmp(f->name, "unknown", 7))
  204. continue;
  205. /* Alternate colors if the vendor changes. */
  206. if (old != NULL && strcmp(old->vendor, f->vendor))
  207. c = !c;
  208. t = f->tested;
  209. s = flashbuses_to_text(f->bustype);
  210. sprintf(vmin, "%0.03f", f->voltage.min / (double)1000);
  211. sprintf(vmax, "%0.03f", f->voltage.max / (double)1000);
  212. /* '{{%s}}' is used in combination with 'OK', 'No' and '?3' to
  213. * select special formatting templates for the bg color. */
  214. printf("|- bgcolor=\"#%s\"\n| %s || %s || align=\"right\" | %d "
  215. "|| %s || {{%s}} || {{%s}} || {{%s}} || {{%s}}"
  216. "|| %s || %s \n",
  217. (c == 1) ? "eeeeee" : "dddddd", f->vendor, f->name,
  218. f->total_size, s,
  219. (t & TEST_OK_PROBE) ? "OK" :
  220. (t & TEST_BAD_PROBE) ? "No" : "?3",
  221. (t & TEST_OK_READ) ? "OK" :
  222. (t & TEST_BAD_READ) ? "No" : "?3",
  223. (t & TEST_OK_ERASE) ? "OK" :
  224. (t & TEST_BAD_ERASE) ? "No" : "?3",
  225. (t & TEST_OK_WRITE) ? "OK" :
  226. (t & TEST_BAD_WRITE) ? "No" : "?3",
  227. f->voltage.min ? vmin : "N/A",
  228. f->voltage.min ? vmax : "N/A");
  229. free(s);
  230. /* Split table into 'cols' columns. */
  231. if (i >= (chipcount / cols + 1)) {
  232. printf("\n|}\n\n| valign=\"top\"|\n\n%s", chip_th);
  233. i = 0;
  234. }
  235. old = f;
  236. }
  237. printf("\n|}\n\n|}\n");
  238. }
  239. /* Not needed for CONFIG_INTERNAL, but for all other PCI-based programmers. */
  240. #if CONFIG_NIC3COM+CONFIG_NICREALTEK+CONFIG_NICNATSEMI+CONFIG_GFXNVIDIA+CONFIG_DRKAISER+CONFIG_SATASII+CONFIG_ATAHPT+CONFIG_NICINTEL+CONFIG_NICINTEL_SPI+CONFIG_OGP_SPI+CONFIG_SATAMV >= 1
  241. static void print_supported_pcidevs_wiki(const struct pcidev_status *devs)
  242. {
  243. int i = 0;
  244. static int c = 0;
  245. /* Alternate colors if the vendor changes. */
  246. c = !c;
  247. for (i = 0; devs[i].vendor_name != NULL; i++) {
  248. printf("|- bgcolor=\"#%s\"\n| %s || %s || "
  249. "%04x:%04x || {{%s}}\n", (c) ? "eeeeee" : "dddddd",
  250. devs[i].vendor_name, devs[i].device_name,
  251. devs[i].vendor_id, devs[i].device_id,
  252. (devs[i].status == NT) ? "?3" : "OK");
  253. }
  254. }
  255. #endif
  256. void print_supported_wiki(void)
  257. {
  258. time_t t = time(NULL);
  259. printf(wiki_header, ctime(&t), flashrom_version);
  260. print_supported_chips_wiki(2);
  261. #if CONFIG_INTERNAL == 1
  262. print_supported_chipsets_wiki(3);
  263. print_supported_boards_wiki();
  264. #endif
  265. printf("%s", programmer_section);
  266. #if CONFIG_NIC3COM == 1
  267. print_supported_pcidevs_wiki(nics_3com);
  268. #endif
  269. #if CONFIG_NICREALTEK == 1
  270. print_supported_pcidevs_wiki(nics_realtek);
  271. #endif
  272. #if CONFIG_NICNATSEMI == 1
  273. print_supported_pcidevs_wiki(nics_natsemi);
  274. #endif
  275. #if CONFIG_GFXNVIDIA == 1
  276. print_supported_pcidevs_wiki(gfx_nvidia);
  277. #endif
  278. #if CONFIG_DRKAISER == 1
  279. print_supported_pcidevs_wiki(drkaiser_pcidev);
  280. #endif
  281. #if CONFIG_SATASII == 1
  282. print_supported_pcidevs_wiki(satas_sii);
  283. #endif
  284. #if CONFIG_ATAHPT == 1
  285. print_supported_pcidevs_wiki(ata_hpt);
  286. #endif
  287. #if CONFIG_NICINTEL == 1
  288. print_supported_pcidevs_wiki(nics_intel);
  289. #endif
  290. #if CONFIG_NICINTEL_SPI == 1
  291. print_supported_pcidevs_wiki(nics_intel_spi);
  292. #endif
  293. #if CONFIG_OGP_SPI == 1
  294. print_supported_pcidevs_wiki(ogp_spi);
  295. #endif
  296. #if CONFIG_SATAMV == 1
  297. print_supported_pcidevs_wiki(satas_mv);
  298. #endif
  299. printf("\n|}\n");
  300. }