You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1491 lines
40 KiB

5 years ago
  1. /*
  2. * ifdtool - dump Intel Firmware Descriptor information
  3. *
  4. * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; version 2 of the License.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #include <unistd.h>
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <getopt.h>
  20. #include <fcntl.h>
  21. #include <sys/types.h>
  22. #include <sys/stat.h>
  23. #include <commonlib/helpers.h>
  24. #include "ifdtool.h"
  25. #ifndef O_BINARY
  26. #define O_BINARY 0
  27. #endif
  28. /**
  29. * PTR_IN_RANGE - examine whether a pointer falls in [base, base + limit)
  30. * @param ptr: the non-void* pointer to a single arbitrary-sized object.
  31. * @param base: base address represented with char* type.
  32. * @param limit: upper limit of the legal address.
  33. *
  34. */
  35. #define PTR_IN_RANGE(ptr, base, limit) \
  36. ((const char *)(ptr) >= (base) && \
  37. (const char *)&(ptr)[1] <= (base) + (limit))
  38. static int ifd_version;
  39. static unsigned int max_regions = 0;
  40. static int selected_chip = 0;
  41. static int platform = -1;
  42. static const struct region_name region_names[MAX_REGIONS] = {
  43. { "Flash Descriptor", "fd", "flashregion_0_flashdescriptor.bin" },
  44. { "BIOS", "bios", "flashregion_1_bios.bin" },
  45. { "Intel ME", "me", "flashregion_2_intel_me.bin" },
  46. { "GbE", "gbe", "flashregion_3_gbe.bin" },
  47. { "Platform Data", "pd", "flashregion_4_platform_data.bin" },
  48. { "Reserved", "res1", "flashregion_5_reserved.bin" },
  49. { "Reserved", "res2", "flashregion_6_reserved.bin" },
  50. { "Reserved", "res3", "flashregion_7_reserved.bin" },
  51. { "EC", "ec", "flashregion_8_ec.bin" },
  52. };
  53. static fdbar_t *find_fd(char *image, int size)
  54. {
  55. int i, found = 0;
  56. /* Scan for FD signature */
  57. for (i = 0; i < (size - 4); i += 4) {
  58. if (*(uint32_t *) (image + i) == 0x0FF0A55A) {
  59. found = 1;
  60. break; // signature found.
  61. }
  62. }
  63. if (!found) {
  64. printf("No Flash Descriptor found in this image\n");
  65. return NULL;
  66. }
  67. fdbar_t *fdb = (fdbar_t *) (image + i);
  68. return PTR_IN_RANGE(fdb, image, size) ? fdb : NULL;
  69. }
  70. static fcba_t *find_fcba(char *image, int size)
  71. {
  72. fdbar_t *fdb = find_fd(image, size);
  73. if (!fdb)
  74. return NULL;
  75. fcba_t *fcba = (fcba_t *) (image + ((fdb->flmap0 & 0xff) << 4));
  76. return PTR_IN_RANGE(fcba, image, size) ? fcba : NULL;
  77. }
  78. static fmba_t *find_fmba(char *image, int size)
  79. {
  80. fdbar_t *fdb = find_fd(image, size);
  81. if (!fdb)
  82. return NULL;
  83. fmba_t *fmba = (fmba_t *) (image + ((fdb->flmap1 & 0xff) << 4));
  84. return PTR_IN_RANGE(fmba, image, size) ? fmba : NULL;
  85. }
  86. static frba_t *find_frba(char *image, int size)
  87. {
  88. fdbar_t *fdb = find_fd(image, size);
  89. if (!fdb)
  90. return NULL;
  91. frba_t *frba =
  92. (frba_t *) (image + (((fdb->flmap0 >> 16) & 0xff) << 4));
  93. return PTR_IN_RANGE(frba, image, size) ? frba : NULL;
  94. }
  95. static fpsba_t *find_fpsba(char *image, int size)
  96. {
  97. fdbar_t *fdb = find_fd(image, size);
  98. if (!fdb)
  99. return NULL;
  100. fpsba_t *fpsba =
  101. (fpsba_t *) (image + (((fdb->flmap1 >> 16) & 0xff) << 4));
  102. return PTR_IN_RANGE(fpsba, image, size) ? fpsba : NULL;
  103. }
  104. static fmsba_t *find_fmsba(char *image, int size)
  105. {
  106. fdbar_t *fdb = find_fd(image, size);
  107. if (!fdb)
  108. return NULL;
  109. fmsba_t *fmsba = (fmsba_t *) (image + ((fdb->flmap2 & 0xff) << 4));
  110. return PTR_IN_RANGE(fmsba, image, size) ? fmsba : NULL;
  111. }
  112. /*
  113. * Some newer platforms have re-defined the FCBA field that was used to
  114. * distinguish IFD v1 v/s v2. Define a list of platforms that we know do not
  115. * have the required FCBA field, but are IFD v2 and return true if current
  116. * platform is one of them.
  117. */
  118. static int is_platform_ifd_2(void)
  119. {
  120. static const int ifd_2_platforms[] = {
  121. PLATFORM_GLK,
  122. PLATFORM_CNL,
  123. };
  124. unsigned int i;
  125. for (i = 0; i < ARRAY_SIZE(ifd_2_platforms); i++) {
  126. if (platform == ifd_2_platforms[i])
  127. return 1;
  128. }
  129. return 0;
  130. }
  131. /*
  132. * There is no version field in the descriptor so to determine
  133. * if this is a new descriptor format we check the hardcoded SPI
  134. * read frequency to see if it is fixed at 20MHz or 17MHz.
  135. */
  136. static int get_ifd_version_from_fcba(char *image, int size)
  137. {
  138. int read_freq;
  139. const fcba_t *fcba = find_fcba(image, size);
  140. if (!fcba)
  141. exit(EXIT_FAILURE);
  142. read_freq = (fcba->flcomp >> 17) & 7;
  143. switch (read_freq) {
  144. case SPI_FREQUENCY_20MHZ:
  145. return IFD_VERSION_1;
  146. case SPI_FREQUENCY_17MHZ:
  147. case SPI_FREQUENCY_50MHZ_30MHZ:
  148. return IFD_VERSION_2;
  149. default:
  150. fprintf(stderr, "Unknown descriptor version: %d\n",
  151. read_freq);
  152. exit(EXIT_FAILURE);
  153. }
  154. }
  155. static void check_ifd_version(char *image, int size)
  156. {
  157. if (is_platform_ifd_2())
  158. ifd_version = IFD_VERSION_2;
  159. else
  160. ifd_version = get_ifd_version_from_fcba(image, size);
  161. if (ifd_version == IFD_VERSION_1)
  162. max_regions = MAX_REGIONS_OLD;
  163. else
  164. max_regions = MAX_REGIONS;
  165. }
  166. static region_t get_region(const frba_t *frba, unsigned int region_type)
  167. {
  168. int base_mask;
  169. int limit_mask;
  170. uint32_t flreg;
  171. region_t region;
  172. if (ifd_version >= IFD_VERSION_2)
  173. base_mask = 0x7fff;
  174. else
  175. base_mask = 0xfff;
  176. limit_mask = base_mask << 16;
  177. if (region_type >= max_regions) {
  178. fprintf(stderr, "Invalid region type %d.\n", region_type);
  179. exit (EXIT_FAILURE);
  180. }
  181. flreg = frba->flreg[region_type];
  182. region.base = (flreg & base_mask) << 12;
  183. region.limit = ((flreg & limit_mask) >> 4) | 0xfff;
  184. region.size = region.limit - region.base + 1;
  185. if (region.size < 0)
  186. region.size = 0;
  187. return region;
  188. }
  189. static void set_region(frba_t *frba, unsigned int region_type,
  190. const region_t *region)
  191. {
  192. if (region_type >= max_regions) {
  193. fprintf(stderr, "Invalid region type %u.\n", region_type);
  194. exit (EXIT_FAILURE);
  195. }
  196. frba->flreg[region_type] =
  197. (((region->limit >> 12) & 0x7fff) << 16) |
  198. ((region->base >> 12) & 0x7fff);
  199. }
  200. static const char *region_name(unsigned int region_type)
  201. {
  202. if (region_type >= max_regions) {
  203. fprintf(stderr, "Invalid region type.\n");
  204. exit (EXIT_FAILURE);
  205. }
  206. return region_names[region_type].pretty;
  207. }
  208. static const char *region_name_short(unsigned int region_type)
  209. {
  210. if (region_type >= max_regions) {
  211. fprintf(stderr, "Invalid region type.\n");
  212. exit (EXIT_FAILURE);
  213. }
  214. return region_names[region_type].terse;
  215. }
  216. static int region_num(const char *name)
  217. {
  218. unsigned int i;
  219. for (i = 0; i < max_regions; i++) {
  220. if (strcasecmp(name, region_names[i].pretty) == 0)
  221. return i;
  222. if (strcasecmp(name, region_names[i].terse) == 0)
  223. return i;
  224. }
  225. return -1;
  226. }
  227. static const char *region_filename(unsigned int region_type)
  228. {
  229. if (region_type >= max_regions) {
  230. fprintf(stderr, "Invalid region type %d.\n", region_type);
  231. exit (EXIT_FAILURE);
  232. }
  233. return region_names[region_type].filename;
  234. }
  235. static void dump_region(unsigned int num, const frba_t *frba)
  236. {
  237. region_t region = get_region(frba, num);
  238. printf(" Flash Region %d (%s): %08x - %08x %s\n",
  239. num, region_name(num), region.base, region.limit,
  240. region.size < 1 ? "(unused)" : "");
  241. }
  242. static void dump_region_layout(char *buf, size_t bufsize, unsigned int num,
  243. const frba_t *frba)
  244. {
  245. region_t region = get_region(frba, num);
  246. snprintf(buf, bufsize, "%08x:%08x %s\n",
  247. region.base, region.limit, region_name_short(num));
  248. }
  249. static void dump_frba(const frba_t *frba)
  250. {
  251. unsigned int i;
  252. printf("Found Region Section\n");
  253. for (i = 0; i < max_regions; i++) {
  254. printf("FLREG%u: 0x%08x\n", i, frba->flreg[i]);
  255. dump_region(i, frba);
  256. }
  257. }
  258. static void dump_frba_layout(const frba_t *frba, const char *layout_fname)
  259. {
  260. char buf[LAYOUT_LINELEN];
  261. size_t bufsize = LAYOUT_LINELEN;
  262. unsigned int i;
  263. int layout_fd = open(layout_fname, O_WRONLY | O_CREAT | O_TRUNC,
  264. S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  265. if (layout_fd == -1) {
  266. perror("Could not open file");
  267. exit(EXIT_FAILURE);
  268. }
  269. for (i = 0; i < max_regions; i++) {
  270. region_t region = get_region(frba, i);
  271. /* is region invalid? */
  272. if (region.size < 1)
  273. continue;
  274. dump_region_layout(buf, bufsize, i, frba);
  275. if (write(layout_fd, buf, strlen(buf)) < 0) {
  276. perror("Could not write to file");
  277. exit(EXIT_FAILURE);
  278. }
  279. }
  280. close(layout_fd);
  281. printf("Wrote layout to %s\n", layout_fname);
  282. }
  283. static void decode_spi_frequency(unsigned int freq)
  284. {
  285. switch (freq) {
  286. case SPI_FREQUENCY_20MHZ:
  287. printf("20MHz");
  288. break;
  289. case SPI_FREQUENCY_33MHZ:
  290. printf("33MHz");
  291. break;
  292. case SPI_FREQUENCY_48MHZ:
  293. printf("48MHz");
  294. break;
  295. case SPI_FREQUENCY_50MHZ_30MHZ:
  296. switch (ifd_version) {
  297. case IFD_VERSION_1:
  298. printf("50MHz");
  299. break;
  300. case IFD_VERSION_2:
  301. printf("30MHz");
  302. break;
  303. }
  304. break;
  305. case SPI_FREQUENCY_17MHZ:
  306. printf("17MHz");
  307. break;
  308. default:
  309. printf("unknown<%x>MHz", freq);
  310. }
  311. }
  312. static void decode_component_density(unsigned int density)
  313. {
  314. switch (density) {
  315. case COMPONENT_DENSITY_512KB:
  316. printf("512KB");
  317. break;
  318. case COMPONENT_DENSITY_1MB:
  319. printf("1MB");
  320. break;
  321. case COMPONENT_DENSITY_2MB:
  322. printf("2MB");
  323. break;
  324. case COMPONENT_DENSITY_4MB:
  325. printf("4MB");
  326. break;
  327. case COMPONENT_DENSITY_8MB:
  328. printf("8MB");
  329. break;
  330. case COMPONENT_DENSITY_16MB:
  331. printf("16MB");
  332. break;
  333. case COMPONENT_DENSITY_32MB:
  334. printf("32MB");
  335. break;
  336. case COMPONENT_DENSITY_64MB:
  337. printf("64MB");
  338. break;
  339. case COMPONENT_DENSITY_UNUSED:
  340. printf("UNUSED");
  341. break;
  342. default:
  343. printf("unknown<%x>MB", density);
  344. }
  345. }
  346. static void dump_fcba(const fcba_t *fcba)
  347. {
  348. printf("\nFound Component Section\n");
  349. printf("FLCOMP 0x%08x\n", fcba->flcomp);
  350. printf(" Dual Output Fast Read Support: %ssupported\n",
  351. (fcba->flcomp & (1 << 30))?"":"not ");
  352. printf(" Read ID/Read Status Clock Frequency: ");
  353. decode_spi_frequency((fcba->flcomp >> 27) & 7);
  354. printf("\n Write/Erase Clock Frequency: ");
  355. decode_spi_frequency((fcba->flcomp >> 24) & 7);
  356. printf("\n Fast Read Clock Frequency: ");
  357. decode_spi_frequency((fcba->flcomp >> 21) & 7);
  358. printf("\n Fast Read Support: %ssupported",
  359. (fcba->flcomp & (1 << 20))?"":"not ");
  360. printf("\n Read Clock Frequency: ");
  361. decode_spi_frequency((fcba->flcomp >> 17) & 7);
  362. switch (ifd_version) {
  363. case IFD_VERSION_1:
  364. printf("\n Component 2 Density: ");
  365. decode_component_density((fcba->flcomp >> 3) & 7);
  366. printf("\n Component 1 Density: ");
  367. decode_component_density(fcba->flcomp & 7);
  368. break;
  369. case IFD_VERSION_2:
  370. printf("\n Component 2 Density: ");
  371. decode_component_density((fcba->flcomp >> 4) & 0xf);
  372. printf("\n Component 1 Density: ");
  373. decode_component_density(fcba->flcomp & 0xf);
  374. break;
  375. }
  376. printf("\n");
  377. printf("FLILL 0x%08x\n", fcba->flill);
  378. printf(" Invalid Instruction 3: 0x%02x\n",
  379. (fcba->flill >> 24) & 0xff);
  380. printf(" Invalid Instruction 2: 0x%02x\n",
  381. (fcba->flill >> 16) & 0xff);
  382. printf(" Invalid Instruction 1: 0x%02x\n",
  383. (fcba->flill >> 8) & 0xff);
  384. printf(" Invalid Instruction 0: 0x%02x\n",
  385. fcba->flill & 0xff);
  386. printf("FLPB 0x%08x\n", fcba->flpb);
  387. printf(" Flash Partition Boundary Address: 0x%06x\n\n",
  388. (fcba->flpb & 0xfff) << 12);
  389. }
  390. static void dump_fpsba(const fpsba_t *fpsba)
  391. {
  392. unsigned int i;
  393. printf("Found PCH Strap Section\n");
  394. for (i = 0; i < ARRAY_SIZE(fpsba->pchstrp); i++)
  395. printf("PCHSTRP%u:%s 0x%08x\n", i,
  396. i < 10 ? " " : "", fpsba->pchstrp[i]);
  397. printf("\n");
  398. }
  399. static void decode_flmstr(uint32_t flmstr)
  400. {
  401. int wr_shift, rd_shift;
  402. if (ifd_version >= IFD_VERSION_2) {
  403. wr_shift = FLMSTR_WR_SHIFT_V2;
  404. rd_shift = FLMSTR_RD_SHIFT_V2;
  405. } else {
  406. wr_shift = FLMSTR_WR_SHIFT_V1;
  407. rd_shift = FLMSTR_RD_SHIFT_V1;
  408. }
  409. /* EC region access only available on v2+ */
  410. if (ifd_version >= IFD_VERSION_2)
  411. printf(" EC Region Write Access: %s\n",
  412. (flmstr & (1 << (wr_shift + 8))) ?
  413. "enabled" : "disabled");
  414. printf(" Platform Data Region Write Access: %s\n",
  415. (flmstr & (1 << (wr_shift + 4))) ? "enabled" : "disabled");
  416. printf(" GbE Region Write Access: %s\n",
  417. (flmstr & (1 << (wr_shift + 3))) ? "enabled" : "disabled");
  418. printf(" Intel ME Region Write Access: %s\n",
  419. (flmstr & (1 << (wr_shift + 2))) ? "enabled" : "disabled");
  420. printf(" Host CPU/BIOS Region Write Access: %s\n",
  421. (flmstr & (1 << (wr_shift + 1))) ? "enabled" : "disabled");
  422. printf(" Flash Descriptor Write Access: %s\n",
  423. (flmstr & (1 << wr_shift)) ? "enabled" : "disabled");
  424. if (ifd_version >= IFD_VERSION_2)
  425. printf(" EC Region Read Access: %s\n",
  426. (flmstr & (1 << (rd_shift + 8))) ?
  427. "enabled" : "disabled");
  428. printf(" Platform Data Region Read Access: %s\n",
  429. (flmstr & (1 << (rd_shift + 4))) ? "enabled" : "disabled");
  430. printf(" GbE Region Read Access: %s\n",
  431. (flmstr & (1 << (rd_shift + 3))) ? "enabled" : "disabled");
  432. printf(" Intel ME Region Read Access: %s\n",
  433. (flmstr & (1 << (rd_shift + 2))) ? "enabled" : "disabled");
  434. printf(" Host CPU/BIOS Region Read Access: %s\n",
  435. (flmstr & (1 << (rd_shift + 1))) ? "enabled" : "disabled");
  436. printf(" Flash Descriptor Read Access: %s\n",
  437. (flmstr & (1 << rd_shift)) ? "enabled" : "disabled");
  438. /* Requestor ID doesn't exist for ifd 2 */
  439. if (ifd_version < IFD_VERSION_2)
  440. printf(" Requester ID: 0x%04x\n\n",
  441. flmstr & 0xffff);
  442. }
  443. static void dump_fmba(const fmba_t *fmba)
  444. {
  445. printf("Found Master Section\n");
  446. printf("FLMSTR1: 0x%08x (Host CPU/BIOS)\n", fmba->flmstr1);
  447. decode_flmstr(fmba->flmstr1);
  448. printf("FLMSTR2: 0x%08x (Intel ME)\n", fmba->flmstr2);
  449. decode_flmstr(fmba->flmstr2);
  450. printf("FLMSTR3: 0x%08x (GbE)\n", fmba->flmstr3);
  451. decode_flmstr(fmba->flmstr3);
  452. if (ifd_version >= IFD_VERSION_2) {
  453. printf("FLMSTR5: 0x%08x (EC)\n", fmba->flmstr5);
  454. decode_flmstr(fmba->flmstr5);
  455. }
  456. }
  457. static void dump_fmsba(const fmsba_t *fmsba)
  458. {
  459. unsigned int i;
  460. printf("Found Processor Strap Section\n");
  461. for (i = 0; i < ARRAY_SIZE(fmsba->data); i++)
  462. printf("????: 0x%08x\n", fmsba->data[i]);
  463. }
  464. static void dump_jid(uint32_t jid)
  465. {
  466. printf(" SPI Componend Device ID 1: 0x%02x\n",
  467. (jid >> 16) & 0xff);
  468. printf(" SPI Componend Device ID 0: 0x%02x\n",
  469. (jid >> 8) & 0xff);
  470. printf(" SPI Componend Vendor ID: 0x%02x\n",
  471. jid & 0xff);
  472. }
  473. static void dump_vscc(uint32_t vscc)
  474. {
  475. printf(" Lower Erase Opcode: 0x%02x\n",
  476. vscc >> 24);
  477. printf(" Lower Write Enable on Write Status: 0x%02x\n",
  478. vscc & (1 << 20) ? 0x06 : 0x50);
  479. printf(" Lower Write Status Required: %s\n",
  480. vscc & (1 << 19) ? "Yes" : "No");
  481. printf(" Lower Write Granularity: %d bytes\n",
  482. vscc & (1 << 18) ? 64 : 1);
  483. printf(" Lower Block / Sector Erase Size: ");
  484. switch ((vscc >> 16) & 0x3) {
  485. case 0:
  486. printf("256 Byte\n");
  487. break;
  488. case 1:
  489. printf("4KB\n");
  490. break;
  491. case 2:
  492. printf("8KB\n");
  493. break;
  494. case 3:
  495. printf("64KB\n");
  496. break;
  497. }
  498. printf(" Upper Erase Opcode: 0x%02x\n",
  499. (vscc >> 8) & 0xff);
  500. printf(" Upper Write Enable on Write Status: 0x%02x\n",
  501. vscc & (1 << 4) ? 0x06 : 0x50);
  502. printf(" Upper Write Status Required: %s\n",
  503. vscc & (1 << 3) ? "Yes" : "No");
  504. printf(" Upper Write Granularity: %d bytes\n",
  505. vscc & (1 << 2) ? 64 : 1);
  506. printf(" Upper Block / Sector Erase Size: ");
  507. switch (vscc & 0x3) {
  508. case 0:
  509. printf("256 Byte\n");
  510. break;
  511. case 1:
  512. printf("4KB\n");
  513. break;
  514. case 2:
  515. printf("8KB\n");
  516. break;
  517. case 3:
  518. printf("64KB\n");
  519. break;
  520. }
  521. }
  522. static void dump_vtba(const vtba_t *vtba, int vtl)
  523. {
  524. int i;
  525. int num = (vtl >> 1) < 8 ? (vtl >> 1) : 8;
  526. printf("ME VSCC table:\n");
  527. for (i = 0; i < num; i++) {
  528. printf(" JID%d: 0x%08x\n", i, vtba->entry[i].jid);
  529. dump_jid(vtba->entry[i].jid);
  530. printf(" VSCC%d: 0x%08x\n", i, vtba->entry[i].vscc);
  531. dump_vscc(vtba->entry[i].vscc);
  532. }
  533. printf("\n");
  534. }
  535. static void dump_oem(const uint8_t *oem)
  536. {
  537. int i, j;
  538. printf("OEM Section:\n");
  539. for (i = 0; i < 4; i++) {
  540. printf("%02x:", i << 4);
  541. for (j = 0; j < 16; j++)
  542. printf(" %02x", oem[(i<<4)+j]);
  543. printf ("\n");
  544. }
  545. printf ("\n");
  546. }
  547. static void dump_fd(char *image, int size)
  548. {
  549. const fdbar_t *fdb = find_fd(image, size);
  550. if (!fdb)
  551. exit(EXIT_FAILURE);
  552. printf("FLMAP0: 0x%08x\n", fdb->flmap0);
  553. printf(" NR: %d\n", (fdb->flmap0 >> 24) & 7);
  554. printf(" FRBA: 0x%x\n", ((fdb->flmap0 >> 16) & 0xff) << 4);
  555. printf(" NC: %d\n", ((fdb->flmap0 >> 8) & 3) + 1);
  556. printf(" FCBA: 0x%x\n", ((fdb->flmap0) & 0xff) << 4);
  557. printf("FLMAP1: 0x%08x\n", fdb->flmap1);
  558. printf(" ISL: 0x%02x\n", (fdb->flmap1 >> 24) & 0xff);
  559. printf(" FPSBA: 0x%x\n", ((fdb->flmap1 >> 16) & 0xff) << 4);
  560. printf(" NM: %d\n", (fdb->flmap1 >> 8) & 3);
  561. printf(" FMBA: 0x%x\n", ((fdb->flmap1) & 0xff) << 4);
  562. printf("FLMAP2: 0x%08x\n", fdb->flmap2);
  563. printf(" PSL: 0x%04x\n", (fdb->flmap2 >> 8) & 0xffff);
  564. printf(" FMSBA: 0x%x\n", ((fdb->flmap2) & 0xff) << 4);
  565. printf("FLUMAP1: 0x%08x\n", fdb->flumap1);
  566. printf(" Intel ME VSCC Table Length (VTL): %d\n",
  567. (fdb->flumap1 >> 8) & 0xff);
  568. printf(" Intel ME VSCC Table Base Address (VTBA): 0x%06x\n\n",
  569. (fdb->flumap1 & 0xff) << 4);
  570. dump_vtba((vtba_t *)
  571. (image + ((fdb->flumap1 & 0xff) << 4)),
  572. (fdb->flumap1 >> 8) & 0xff);
  573. dump_oem((const uint8_t *)image + 0xf00);
  574. const frba_t *frba = find_frba(image, size);
  575. const fcba_t *fcba = find_fcba(image, size);
  576. const fpsba_t *fpsba = find_fpsba(image, size);
  577. const fmba_t *fmba = find_fmba(image, size);
  578. const fmsba_t *fmsba = find_fmsba(image, size);
  579. if (frba && fcba && fpsba && fmba && fmsba) {
  580. dump_frba(frba);
  581. dump_fcba(fcba);
  582. dump_fpsba(fpsba);
  583. dump_fmba(fmba);
  584. dump_fmsba(fmsba);
  585. } else {
  586. printf("FD is corrupted!\n");
  587. }
  588. }
  589. static void dump_layout(char *image, int size, const char *layout_fname)
  590. {
  591. const frba_t *frba = find_frba(image, size);
  592. if (!frba)
  593. exit(EXIT_FAILURE);
  594. dump_frba_layout(frba, layout_fname);
  595. }
  596. static void write_regions(char *image, int size)
  597. {
  598. unsigned int i;
  599. const frba_t *frba = find_frba(image, size);
  600. if (!frba)
  601. exit(EXIT_FAILURE);
  602. for (i = 0; i < max_regions; i++) {
  603. region_t region = get_region(frba, i);
  604. dump_region(i, frba);
  605. if (region.size > 0) {
  606. int region_fd;
  607. region_fd = open(region_filename(i),
  608. O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
  609. S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  610. if (region_fd < 0) {
  611. perror("Error while trying to open file");
  612. exit(EXIT_FAILURE);
  613. }
  614. if (write(region_fd, image + region.base, region.size) != region.size)
  615. perror("Error while writing");
  616. close(region_fd);
  617. }
  618. }
  619. }
  620. static void write_image(const char *filename, char *image, int size)
  621. {
  622. char new_filename[FILENAME_MAX]; // allow long file names
  623. int new_fd;
  624. // - 5: leave room for ".new\0"
  625. strncpy(new_filename, filename, FILENAME_MAX - 5);
  626. strncat(new_filename, ".new", FILENAME_MAX - strlen(filename));
  627. printf("Writing new image to %s\n", new_filename);
  628. // Now write out new image
  629. new_fd = open(new_filename,
  630. O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
  631. S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  632. if (new_fd < 0) {
  633. perror("Error while trying to open file");
  634. exit(EXIT_FAILURE);
  635. }
  636. if (write(new_fd, image, size) != size)
  637. perror("Error while writing");
  638. close(new_fd);
  639. }
  640. static void set_spi_frequency(const char *filename, char *image, int size,
  641. enum spi_frequency freq)
  642. {
  643. fcba_t *fcba = find_fcba(image, size);
  644. if (!fcba)
  645. exit(EXIT_FAILURE);
  646. /* clear bits 21-29 */
  647. fcba->flcomp &= ~0x3fe00000;
  648. /* Read ID and Read Status Clock Frequency */
  649. fcba->flcomp |= freq << 27;
  650. /* Write and Erase Clock Frequency */
  651. fcba->flcomp |= freq << 24;
  652. /* Fast Read Clock Frequency */
  653. fcba->flcomp |= freq << 21;
  654. write_image(filename, image, size);
  655. }
  656. static void set_em100_mode(const char *filename, char *image, int size)
  657. {
  658. fcba_t *fcba = find_fcba(image, size);
  659. if (!fcba)
  660. exit(EXIT_FAILURE);
  661. int freq;
  662. switch (ifd_version) {
  663. case IFD_VERSION_1:
  664. freq = SPI_FREQUENCY_20MHZ;
  665. break;
  666. case IFD_VERSION_2:
  667. freq = SPI_FREQUENCY_17MHZ;
  668. break;
  669. default:
  670. freq = SPI_FREQUENCY_17MHZ;
  671. break;
  672. }
  673. fcba->flcomp &= ~(1 << 30);
  674. set_spi_frequency(filename, image, size, freq);
  675. }
  676. static void set_chipdensity(const char *filename, char *image, int size,
  677. unsigned int density)
  678. {
  679. fcba_t *fcba = find_fcba(image, size);
  680. if (!fcba)
  681. exit(EXIT_FAILURE);
  682. printf("Setting chip density to ");
  683. decode_component_density(density);
  684. printf("\n");
  685. switch (ifd_version) {
  686. case IFD_VERSION_1:
  687. /* fail if selected density is not supported by this version */
  688. if ( (density == COMPONENT_DENSITY_32MB) ||
  689. (density == COMPONENT_DENSITY_64MB) ||
  690. (density == COMPONENT_DENSITY_UNUSED) ) {
  691. printf("error: Selected density not supported in IFD version 1.\n");
  692. exit(EXIT_FAILURE);
  693. }
  694. break;
  695. case IFD_VERSION_2:
  696. /* I do not have a version 2 IFD nor do i have the docs. */
  697. printf("error: Changing the chip density for IFD version 2 has not been"
  698. " implemented yet.\n");
  699. exit(EXIT_FAILURE);
  700. default:
  701. printf("error: Unknown IFD version\n");
  702. exit(EXIT_FAILURE);
  703. break;
  704. }
  705. /* clear chip density for corresponding chip */
  706. switch (selected_chip) {
  707. case 1:
  708. fcba->flcomp &= ~(0x7);
  709. break;
  710. case 2:
  711. fcba->flcomp &= ~(0x7 << 3);
  712. break;
  713. default: /*both chips*/
  714. fcba->flcomp &= ~(0x3F);
  715. break;
  716. }
  717. /* set the new density */
  718. if (selected_chip == 1 || selected_chip == 0)
  719. fcba->flcomp |= (density); /* first chip */
  720. if (selected_chip == 2 || selected_chip == 0)
  721. fcba->flcomp |= (density << 3); /* second chip */
  722. write_image(filename, image, size);
  723. }
  724. static void lock_descriptor(const char *filename, char *image, int size)
  725. {
  726. int wr_shift, rd_shift;
  727. fmba_t *fmba = find_fmba(image, size);
  728. if (!fmba)
  729. exit(EXIT_FAILURE);
  730. /* TODO: Dynamically take Platform Data Region and GbE Region
  731. * into regard.
  732. */
  733. if (ifd_version >= IFD_VERSION_2) {
  734. wr_shift = FLMSTR_WR_SHIFT_V2;
  735. rd_shift = FLMSTR_RD_SHIFT_V2;
  736. /* Clear non-reserved bits */
  737. fmba->flmstr1 &= 0xff;
  738. fmba->flmstr2 &= 0xff;
  739. fmba->flmstr3 &= 0xff;
  740. } else {
  741. wr_shift = FLMSTR_WR_SHIFT_V1;
  742. rd_shift = FLMSTR_RD_SHIFT_V1;
  743. fmba->flmstr1 = 0;
  744. fmba->flmstr2 = 0;
  745. /* Requestor ID */
  746. fmba->flmstr3 = 0x118;
  747. }
  748. switch (platform) {
  749. case PLATFORM_APL:
  750. case PLATFORM_GLK:
  751. /* CPU/BIOS can read descriptor and BIOS */
  752. fmba->flmstr1 |= 0x3 << rd_shift;
  753. /* CPU/BIOS can write BIOS */
  754. fmba->flmstr1 |= 0x2 << wr_shift;
  755. /* TXE can read descriptor, BIOS and Device Expansion */
  756. fmba->flmstr2 |= 0x23 << rd_shift;
  757. /* TXE can only write Device Expansion */
  758. fmba->flmstr2 |= 0x20 << wr_shift;
  759. break;
  760. case PLATFORM_SKLKBL:
  761. /* CPU/BIOS can read descriptor, BIOS and GbE. */
  762. fmba->flmstr1 |= 0xb << rd_shift;
  763. /* CPU/BIOS can write BIOS and Gbe. */
  764. fmba->flmstr1 |= 0xa << wr_shift;
  765. /* ME can read descriptor, ME and GbE. */
  766. fmba->flmstr2 |= 0xd << rd_shift;
  767. /* ME can write ME. */
  768. fmba->flmstr2 |= 0x4 << wr_shift;
  769. /* GbE can read GbE and descriptor. */
  770. fmba->flmstr3 |= 0x9 << rd_shift;
  771. /* GbE can write GbE. */
  772. fmba->flmstr3 |= 0x8 << wr_shift;
  773. /* EC can read EC and descriptor. */
  774. fmba->flmstr5 |= 0x101 << rd_shift;
  775. /* EC can write EC region. */
  776. fmba->flmstr5 |= 0x100 << wr_shift;
  777. break;
  778. default:
  779. /* CPU/BIOS can read descriptor, BIOS, and GbE. */
  780. fmba->flmstr1 |= 0xb << rd_shift;
  781. /* CPU/BIOS can write BIOS and GbE. */
  782. fmba->flmstr1 |= 0xa << wr_shift;
  783. /* ME can read descriptor, ME, and GbE. */
  784. fmba->flmstr2 |= 0xd << rd_shift;
  785. /* ME can write ME and GbE. */
  786. fmba->flmstr2 |= 0xc << wr_shift;
  787. /* GbE can write only GbE. */
  788. fmba->flmstr3 |= 0x8 << rd_shift;
  789. /* GbE can read only GbE. */
  790. fmba->flmstr3 |= 0x8 << wr_shift;
  791. break;
  792. }
  793. write_image(filename, image, size);
  794. }
  795. static void unlock_descriptor(const char *filename, char *image, int size)
  796. {
  797. fmba_t *fmba = find_fmba(image, size);
  798. if (!fmba)
  799. exit(EXIT_FAILURE);
  800. if (ifd_version >= IFD_VERSION_2) {
  801. /* Access bits for each region are read: 19:8 write: 31:20 */
  802. fmba->flmstr1 = 0xffffff00 | (fmba->flmstr1 & 0xff);
  803. fmba->flmstr2 = 0xffffff00 | (fmba->flmstr2 & 0xff);
  804. fmba->flmstr3 = 0xffffff00 | (fmba->flmstr3 & 0xff);
  805. } else {
  806. fmba->flmstr1 = 0xffff0000;
  807. fmba->flmstr2 = 0xffff0000;
  808. /* Keep chipset specific Requester ID */
  809. fmba->flmstr3 = 0x08080000 | (fmba->flmstr3 & 0xffff);
  810. }
  811. write_image(filename, image, size);
  812. }
  813. void inject_region(const char *filename, char *image, int size,
  814. unsigned int region_type, const char *region_fname)
  815. {
  816. frba_t *frba = find_frba(image, size);
  817. if (!frba)
  818. exit(EXIT_FAILURE);
  819. region_t region = get_region(frba, region_type);
  820. if (region.size <= 0xfff) {
  821. fprintf(stderr, "Region %s is disabled in target. Not injecting.\n",
  822. region_name(region_type));
  823. exit(EXIT_FAILURE);
  824. }
  825. int region_fd = open(region_fname, O_RDONLY | O_BINARY);
  826. if (region_fd == -1) {
  827. perror("Could not open file");
  828. exit(EXIT_FAILURE);
  829. }
  830. struct stat buf;
  831. if (fstat(region_fd, &buf) == -1) {
  832. perror("Could not stat file");
  833. exit(EXIT_FAILURE);
  834. }
  835. int region_size = buf.st_size;
  836. printf("File %s is %d bytes\n", region_fname, region_size);
  837. if ( (region_size > region.size) || ((region_type != 1) &&
  838. (region_size > region.size))) {
  839. fprintf(stderr, "Region %s is %d(0x%x) bytes. File is %d(0x%x)"
  840. " bytes. Not injecting.\n",
  841. region_name(region_type), region.size,
  842. region.size, region_size, region_size);
  843. exit(EXIT_FAILURE);
  844. }
  845. int offset = 0;
  846. if ((region_type == 1) && (region_size < region.size)) {
  847. fprintf(stderr, "Region %s is %d(0x%x) bytes. File is %d(0x%x)"
  848. " bytes. Padding before injecting.\n",
  849. region_name(region_type), region.size,
  850. region.size, region_size, region_size);
  851. offset = region.size - region_size;
  852. memset(image + region.base, 0xff, offset);
  853. }
  854. if (size < region.base + offset + region_size) {
  855. fprintf(stderr, "Output file is too small. (%d < %d)\n",
  856. size, region.base + offset + region_size);
  857. exit(EXIT_FAILURE);
  858. }
  859. if (read(region_fd, image + region.base + offset, region_size)
  860. != region_size) {
  861. perror("Could not read file");
  862. exit(EXIT_FAILURE);
  863. }
  864. close(region_fd);
  865. printf("Adding %s as the %s section of %s\n",
  866. region_fname, region_name(region_type), filename);
  867. write_image(filename, image, size);
  868. }
  869. unsigned int next_pow2(unsigned int x)
  870. {
  871. unsigned int y = 1;
  872. if (x == 0)
  873. return 0;
  874. while (y <= x)
  875. y = y << 1;
  876. return y;
  877. }
  878. /**
  879. * Determine if two memory regions overlap.
  880. *
  881. * @param r1, r2 Memory regions to compare.
  882. * @return 0 if the two regions are seperate
  883. * @return 1 if the two regions overlap
  884. */
  885. static int regions_collide(const region_t *r1, const region_t *r2)
  886. {
  887. if ((r1->size == 0) || (r2->size == 0))
  888. return 0;
  889. if ( ((r1->base >= r2->base) && (r1->base <= r2->limit)) ||
  890. ((r1->limit >= r2->base) && (r1->limit <= r2->limit)) )
  891. return 1;
  892. return 0;
  893. }
  894. void new_layout(const char *filename, char *image, int size,
  895. const char *layout_fname)
  896. {
  897. FILE *romlayout;
  898. char tempstr[256];
  899. char layout_region_name[256];
  900. unsigned int i, j;
  901. int region_number;
  902. region_t current_regions[MAX_REGIONS];
  903. region_t new_regions[MAX_REGIONS];
  904. int new_extent = 0;
  905. char *new_image;
  906. /* load current descriptor map and regions */
  907. frba_t *frba = find_frba(image, size);
  908. if (!frba)
  909. exit(EXIT_FAILURE);
  910. for (i = 0; i < max_regions; i++) {
  911. current_regions[i] = get_region(frba, i);
  912. new_regions[i] = get_region(frba, i);
  913. }
  914. /* read new layout */
  915. romlayout = fopen(layout_fname, "r");
  916. if (!romlayout) {
  917. perror("Could not read layout file.\n");
  918. exit(EXIT_FAILURE);
  919. }
  920. while (!feof(romlayout)) {
  921. char *tstr1, *tstr2;
  922. if (2 != fscanf(romlayout, "%255s %255s\n", tempstr,
  923. layout_region_name))
  924. continue;
  925. region_number = region_num(layout_region_name);
  926. if (region_number < 0)
  927. continue;
  928. tstr1 = strtok(tempstr, ":");
  929. tstr2 = strtok(NULL, ":");
  930. if (!tstr1 || !tstr2) {
  931. fprintf(stderr, "Could not parse layout file.\n");
  932. exit(EXIT_FAILURE);
  933. }
  934. new_regions[region_number].base = strtol(tstr1,
  935. (char **)NULL, 16);
  936. new_regions[region_number].limit = strtol(tstr2,
  937. (char **)NULL, 16);
  938. new_regions[region_number].size =
  939. new_regions[region_number].limit -
  940. new_regions[region_number].base + 1;
  941. if (new_regions[region_number].size < 0)
  942. new_regions[region_number].size = 0;
  943. }
  944. fclose(romlayout);
  945. /* check new layout */
  946. for (i = 0; i < max_regions; i++) {
  947. if (new_regions[i].size == 0)
  948. continue;
  949. if (new_regions[i].size < current_regions[i].size) {
  950. printf("DANGER: Region %s is shrinking.\n",
  951. region_name(i));
  952. printf(" The region will be truncated to fit.\n");
  953. printf(" This may result in an unusable image.\n");
  954. }
  955. for (j = i + 1; j < max_regions; j++) {
  956. if (regions_collide(&new_regions[i], &new_regions[j])) {
  957. fprintf(stderr, "Regions would overlap.\n");
  958. exit(EXIT_FAILURE);
  959. }
  960. }
  961. /* detect if the image size should grow */
  962. if (new_extent < new_regions[i].limit)
  963. new_extent = new_regions[i].limit;
  964. }
  965. new_extent = next_pow2(new_extent - 1);
  966. if (new_extent != size) {
  967. printf("The image has changed in size.\n");
  968. printf("The old image is %d bytes.\n", size);
  969. printf("The new image is %d bytes.\n", new_extent);
  970. }
  971. /* copy regions to a new image */
  972. new_image = malloc(new_extent);
  973. memset(new_image, 0xff, new_extent);
  974. for (i = 0; i < max_regions; i++) {
  975. int copy_size = new_regions[i].size;
  976. int offset_current = 0, offset_new = 0;
  977. const region_t *current = &current_regions[i];
  978. const region_t *new = &new_regions[i];
  979. if (new->size == 0)
  980. continue;
  981. if (new->size > current->size) {
  982. /* copy from the end of the current region */
  983. copy_size = current->size;
  984. offset_new = new->size - current->size;
  985. }
  986. if (new->size < current->size) {
  987. /* copy to the end of the new region */
  988. offset_current = current->size - new->size;
  989. }
  990. printf("Copy Descriptor %d (%s) (%d bytes)\n", i,
  991. region_name(i), copy_size);
  992. printf(" from %08x+%08x:%08x (%10d)\n", current->base,
  993. offset_current, current->limit, current->size);
  994. printf(" to %08x+%08x:%08x (%10d)\n", new->base,
  995. offset_new, new->limit, new->size);
  996. memcpy(new_image + new->base + offset_new,
  997. image + current->base + offset_current,
  998. copy_size);
  999. }
  1000. /* update new descriptor regions */
  1001. frba = find_frba(new_image, new_extent);
  1002. if (!frba)
  1003. exit(EXIT_FAILURE);
  1004. for (i = 1; i < max_regions; i++)
  1005. set_region(frba, i, &new_regions[i]);
  1006. write_image(filename, new_image, new_extent);
  1007. free(new_image);
  1008. }
  1009. static void print_version(void)
  1010. {
  1011. printf("ifdtool v%s -- ", IFDTOOL_VERSION);
  1012. printf("Copyright (C) 2011 Google Inc.\n\n");
  1013. printf
  1014. ("This program is free software: you can redistribute it and/or modify\n"
  1015. "it under the terms of the GNU General Public License as published by\n"
  1016. "the Free Software Foundation, version 2 of the License.\n\n"
  1017. "This program is distributed in the hope that it will be useful,\n"
  1018. "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
  1019. "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
  1020. "GNU General Public License for more details.\n\n");
  1021. }
  1022. static void print_usage(const char *name)
  1023. {
  1024. printf("usage: %s [-vhdix?] <filename>\n", name);
  1025. printf("\n"
  1026. " -d | --dump: dump intel firmware descriptor\n"
  1027. " -f | --layout <filename> dump regions into a flashrom layout file\n"
  1028. " -x | --extract: extract intel fd modules\n"
  1029. " -i | --inject <region>:<module> inject file <module> into region <region>\n"
  1030. " -n | --newlayout <filename> update regions using a flashrom layout file\n"
  1031. " -s | --spifreq <17|20|30|33|48|50> set the SPI frequency\n"
  1032. " -D | --density <512|1|2|4|8|16> set chip density (512 in KByte, others in MByte)\n"
  1033. " -C | --chip <0|1|2> select spi chip on which to operate\n"
  1034. " can only be used once per run:\n"
  1035. " 0 - both chips (default), 1 - first chip, 2 - second chip\n"
  1036. " -e | --em100 set SPI frequency to 20MHz and disable\n"
  1037. " Dual Output Fast Read Support\n"
  1038. " -l | --lock Lock firmware descriptor and ME region\n"
  1039. " -u | --unlock Unlock firmware descriptor and ME region\n"
  1040. " -p | --platform Add platform-specific quirks\n"
  1041. " aplk - Apollo Lake\n"
  1042. " cnl - Cannon Lake\n"
  1043. " glk - Gemini Lake\n"
  1044. " sklkbl - Skylake/Kaby Lake\n"
  1045. " -v | --version: print the version\n"
  1046. " -h | --help: print this help\n\n"
  1047. "<region> is one of Descriptor, BIOS, ME, GbE, Platform\n"
  1048. "\n");
  1049. }
  1050. int main(int argc, char *argv[])
  1051. {
  1052. int opt, option_index = 0;
  1053. int mode_dump = 0, mode_extract = 0, mode_inject = 0, mode_spifreq = 0;
  1054. int mode_em100 = 0, mode_locked = 0, mode_unlocked = 0;
  1055. int mode_layout = 0, mode_newlayout = 0, mode_density = 0;
  1056. char *region_type_string = NULL, *region_fname = NULL;
  1057. const char *layout_fname = NULL;
  1058. int region_type = -1, inputfreq = 0;
  1059. unsigned int new_density = 0;
  1060. enum spi_frequency spifreq = SPI_FREQUENCY_20MHZ;
  1061. static const struct option long_options[] = {
  1062. {"dump", 0, NULL, 'd'},
  1063. {"layout", 1, NULL, 'f'},
  1064. {"extract", 0, NULL, 'x'},
  1065. {"inject", 1, NULL, 'i'},
  1066. {"newlayout", 1, NULL, 'n'},
  1067. {"spifreq", 1, NULL, 's'},
  1068. {"density", 1, NULL, 'D'},
  1069. {"chip", 1, NULL, 'C'},
  1070. {"em100", 0, NULL, 'e'},
  1071. {"lock", 0, NULL, 'l'},
  1072. {"unlock", 0, NULL, 'u'},
  1073. {"version", 0, NULL, 'v'},
  1074. {"help", 0, NULL, 'h'},
  1075. {"platform", 0, NULL, 'p'},
  1076. {0, 0, 0, 0}
  1077. };
  1078. while ((opt = getopt_long(argc, argv, "df:D:C:xi:n:s:p:eluvh?",
  1079. long_options, &option_index)) != EOF) {
  1080. switch (opt) {
  1081. case 'd':
  1082. mode_dump = 1;
  1083. break;
  1084. case 'f':
  1085. mode_layout = 1;
  1086. layout_fname = strdup(optarg);
  1087. if (!layout_fname) {
  1088. fprintf(stderr, "No layout file specified\n");
  1089. print_usage(argv[0]);
  1090. exit(EXIT_FAILURE);
  1091. }
  1092. break;
  1093. case 'x':
  1094. mode_extract = 1;
  1095. break;
  1096. case 'i':
  1097. // separate type and file name
  1098. region_type_string = strdup(optarg);
  1099. region_fname = strchr(region_type_string, ':');
  1100. if (!region_fname) {
  1101. print_usage(argv[0]);
  1102. exit(EXIT_FAILURE);
  1103. }
  1104. region_fname[0] = '\0';
  1105. region_fname++;
  1106. // Descriptor, BIOS, ME, GbE, Platform
  1107. // valid type?
  1108. if (!strcasecmp("Descriptor", region_type_string))
  1109. region_type = 0;
  1110. else if (!strcasecmp("BIOS", region_type_string))
  1111. region_type = 1;
  1112. else if (!strcasecmp("ME", region_type_string))
  1113. region_type = 2;
  1114. else if (!strcasecmp("GbE", region_type_string))
  1115. region_type = 3;
  1116. else if (!strcasecmp("Platform", region_type_string))
  1117. region_type = 4;
  1118. else if (!strcasecmp("EC", region_type_string))
  1119. region_type = 8;
  1120. if (region_type == -1) {
  1121. fprintf(stderr, "No such region type: '%s'\n\n",
  1122. region_type_string);
  1123. print_usage(argv[0]);
  1124. exit(EXIT_FAILURE);
  1125. }
  1126. mode_inject = 1;
  1127. break;
  1128. case 'n':
  1129. mode_newlayout = 1;
  1130. layout_fname = strdup(optarg);
  1131. if (!layout_fname) {
  1132. fprintf(stderr, "No layout file specified\n");
  1133. print_usage(argv[0]);
  1134. exit(EXIT_FAILURE);
  1135. }
  1136. break;
  1137. case 'D':
  1138. mode_density = 1;
  1139. new_density = strtoul(optarg, NULL, 0);
  1140. switch (new_density) {
  1141. case 512:
  1142. new_density = COMPONENT_DENSITY_512KB;
  1143. break;
  1144. case 1:
  1145. new_density = COMPONENT_DENSITY_1MB;
  1146. break;
  1147. case 2:
  1148. new_density = COMPONENT_DENSITY_2MB;
  1149. break;
  1150. case 4:
  1151. new_density = COMPONENT_DENSITY_4MB;
  1152. break;
  1153. case 8:
  1154. new_density = COMPONENT_DENSITY_8MB;
  1155. break;
  1156. case 16:
  1157. new_density = COMPONENT_DENSITY_16MB;
  1158. break;
  1159. case 32:
  1160. new_density = COMPONENT_DENSITY_32MB;
  1161. break;
  1162. case 64:
  1163. new_density = COMPONENT_DENSITY_64MB;
  1164. break;
  1165. case 0:
  1166. new_density = COMPONENT_DENSITY_UNUSED;
  1167. break;
  1168. default:
  1169. printf("error: Unknown density\n");
  1170. print_usage(argv[0]);
  1171. exit(EXIT_FAILURE);
  1172. }
  1173. break;
  1174. case 'C':
  1175. selected_chip = strtol(optarg, NULL, 0);
  1176. if (selected_chip > 2) {
  1177. fprintf(stderr, "error: Invalid chip selection\n");
  1178. print_usage(argv[0]);
  1179. exit(EXIT_FAILURE);
  1180. }
  1181. break;
  1182. case 's':
  1183. // Parse the requested SPI frequency
  1184. inputfreq = strtol(optarg, NULL, 0);
  1185. switch (inputfreq) {
  1186. case 17:
  1187. spifreq = SPI_FREQUENCY_17MHZ;
  1188. break;
  1189. case 20:
  1190. spifreq = SPI_FREQUENCY_20MHZ;
  1191. break;
  1192. case 30:
  1193. spifreq = SPI_FREQUENCY_50MHZ_30MHZ;
  1194. break;
  1195. case 33:
  1196. spifreq = SPI_FREQUENCY_33MHZ;
  1197. break;
  1198. case 48:
  1199. spifreq = SPI_FREQUENCY_48MHZ;
  1200. break;
  1201. case 50:
  1202. spifreq = SPI_FREQUENCY_50MHZ_30MHZ;
  1203. break;
  1204. default:
  1205. fprintf(stderr, "Invalid SPI Frequency: %d\n",
  1206. inputfreq);
  1207. print_usage(argv[0]);
  1208. exit(EXIT_FAILURE);
  1209. }
  1210. mode_spifreq = 1;
  1211. break;
  1212. case 'e':
  1213. mode_em100 = 1;
  1214. break;
  1215. case 'l':
  1216. mode_locked = 1;
  1217. if (mode_unlocked == 1) {
  1218. fprintf(stderr, "Locking/Unlocking FD and ME are mutually exclusive\n");
  1219. exit(EXIT_FAILURE);
  1220. }
  1221. break;
  1222. case 'u':
  1223. mode_unlocked = 1;
  1224. if (mode_locked == 1) {
  1225. fprintf(stderr, "Locking/Unlocking FD and ME are mutually exclusive\n");
  1226. exit(EXIT_FAILURE);
  1227. }
  1228. break;
  1229. case 'p':
  1230. if (!strcmp(optarg, "aplk")) {
  1231. platform = PLATFORM_APL;
  1232. } else if (!strcmp(optarg, "cnl")) {
  1233. platform = PLATFORM_CNL;
  1234. } else if (!strcmp(optarg, "glk")) {
  1235. platform = PLATFORM_GLK;
  1236. } else if (!strcmp(optarg, "sklkbl")) {
  1237. platform = PLATFORM_SKLKBL;
  1238. } else {
  1239. fprintf(stderr, "Unknown platform: %s\n", optarg);
  1240. exit(EXIT_FAILURE);
  1241. }
  1242. fprintf(stderr, "Platform is: %s\n", optarg);
  1243. break;
  1244. case 'v':
  1245. print_version();
  1246. exit(EXIT_SUCCESS);
  1247. break;
  1248. case 'h':
  1249. case '?':
  1250. default:
  1251. print_usage(argv[0]);
  1252. exit(EXIT_SUCCESS);
  1253. break;
  1254. }
  1255. }
  1256. if ((mode_dump + mode_layout + mode_extract + mode_inject +
  1257. mode_newlayout + (mode_spifreq | mode_em100 | mode_unlocked |
  1258. mode_locked)) > 1) {
  1259. fprintf(stderr, "You may not specify more than one mode.\n\n");
  1260. print_usage(argv[0]);
  1261. exit(EXIT_FAILURE);
  1262. }
  1263. if ((mode_dump + mode_layout + mode_extract + mode_inject +
  1264. mode_newlayout + mode_spifreq + mode_em100 + mode_locked +
  1265. mode_unlocked + mode_density) == 0) {
  1266. fprintf(stderr, "You need to specify a mode.\n\n");
  1267. print_usage(argv[0]);
  1268. exit(EXIT_FAILURE);
  1269. }
  1270. if (optind + 1 != argc) {
  1271. fprintf(stderr, "You need to specify a file.\n\n");
  1272. print_usage(argv[0]);
  1273. exit(EXIT_FAILURE);
  1274. }
  1275. char *filename = argv[optind];
  1276. int bios_fd = open(filename, O_RDONLY | O_BINARY);
  1277. if (bios_fd == -1) {
  1278. perror("Could not open file");
  1279. exit(EXIT_FAILURE);
  1280. }
  1281. struct stat buf;
  1282. if (fstat(bios_fd, &buf) == -1) {
  1283. perror("Could not stat file");
  1284. exit(EXIT_FAILURE);
  1285. }
  1286. int size = buf.st_size;
  1287. printf("File %s is %d bytes\n", filename, size);
  1288. char *image = malloc(size);
  1289. if (!image) {
  1290. printf("Out of memory.\n");
  1291. exit(EXIT_FAILURE);
  1292. }
  1293. if (read(bios_fd, image, size) != size) {
  1294. perror("Could not read file");
  1295. exit(EXIT_FAILURE);
  1296. }
  1297. close(bios_fd);
  1298. check_ifd_version(image, size);
  1299. if (mode_dump)
  1300. dump_fd(image, size);
  1301. if (mode_layout)
  1302. dump_layout(image, size, layout_fname);
  1303. if (mode_extract)
  1304. write_regions(image, size);
  1305. if (mode_inject)
  1306. inject_region(filename, image, size, region_type,
  1307. region_fname);
  1308. if (mode_newlayout)
  1309. new_layout(filename, image, size, layout_fname);
  1310. if (mode_spifreq)
  1311. set_spi_frequency(filename, image, size, spifreq);
  1312. if (mode_density)
  1313. set_chipdensity(filename, image, size, new_density);
  1314. if (mode_em100)
  1315. set_em100_mode(filename, image, size);
  1316. if (mode_locked)
  1317. lock_descriptor(filename, image, size);
  1318. if (mode_unlocked)
  1319. unlock_descriptor(filename, image, size);
  1320. free(image);
  1321. return 0;
  1322. }