eprom.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. // SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause
  2. /*
  3. * Copyright(c) 2015, 2016 Intel Corporation.
  4. */
  5. #include <linux/delay.h>
  6. #include "hfi.h"
  7. #include "common.h"
  8. #include "eprom.h"
  9. /*
  10. * The EPROM is logically divided into three partitions:
  11. * partition 0: the first 128K, visible from PCI ROM BAR
  12. * partition 1: 4K config file (sector size)
  13. * partition 2: the rest
  14. */
  15. #define P0_SIZE (128 * 1024)
  16. #define P1_SIZE (4 * 1024)
  17. #define P1_START P0_SIZE
  18. #define P2_START (P0_SIZE + P1_SIZE)
  19. /* controller page size, in bytes */
  20. #define EP_PAGE_SIZE 256
  21. #define EP_PAGE_MASK (EP_PAGE_SIZE - 1)
  22. #define EP_PAGE_DWORDS (EP_PAGE_SIZE / sizeof(u32))
  23. /* controller commands */
  24. #define CMD_SHIFT 24
  25. #define CMD_NOP (0)
  26. #define CMD_READ_DATA(addr) ((0x03 << CMD_SHIFT) | addr)
  27. #define CMD_RELEASE_POWERDOWN_NOID ((0xab << CMD_SHIFT))
  28. /* controller interface speeds */
  29. #define EP_SPEED_FULL 0x2 /* full speed */
  30. /*
  31. * How long to wait for the EPROM to become available, in ms.
  32. * The spec 32 Mb EPROM takes around 40s to erase then write.
  33. * Double it for safety.
  34. */
  35. #define EPROM_TIMEOUT 80000 /* ms */
  36. /*
  37. * Read a 256 byte (64 dword) EPROM page.
  38. * All callers have verified the offset is at a page boundary.
  39. */
  40. static void read_page(struct hfi1_devdata *dd, u32 offset, u32 *result)
  41. {
  42. int i;
  43. write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_READ_DATA(offset));
  44. for (i = 0; i < EP_PAGE_DWORDS; i++)
  45. result[i] = (u32)read_csr(dd, ASIC_EEP_DATA);
  46. write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_NOP); /* close open page */
  47. }
  48. /*
  49. * Read length bytes starting at offset from the start of the EPROM.
  50. */
  51. static int read_length(struct hfi1_devdata *dd, u32 start, u32 len, void *dest)
  52. {
  53. u32 buffer[EP_PAGE_DWORDS];
  54. u32 end;
  55. u32 start_offset;
  56. u32 read_start;
  57. u32 bytes;
  58. if (len == 0)
  59. return 0;
  60. end = start + len;
  61. /*
  62. * Make sure the read range is not outside of the controller read
  63. * command address range. Note that '>' is correct below - the end
  64. * of the range is OK if it stops at the limit, but no higher.
  65. */
  66. if (end > (1 << CMD_SHIFT))
  67. return -EINVAL;
  68. /* read the first partial page */
  69. start_offset = start & EP_PAGE_MASK;
  70. if (start_offset) {
  71. /* partial starting page */
  72. /* align and read the page that contains the start */
  73. read_start = start & ~EP_PAGE_MASK;
  74. read_page(dd, read_start, buffer);
  75. /* the rest of the page is available data */
  76. bytes = EP_PAGE_SIZE - start_offset;
  77. if (len <= bytes) {
  78. /* end is within this page */
  79. memcpy(dest, (u8 *)buffer + start_offset, len);
  80. return 0;
  81. }
  82. memcpy(dest, (u8 *)buffer + start_offset, bytes);
  83. start += bytes;
  84. len -= bytes;
  85. dest += bytes;
  86. }
  87. /* start is now page aligned */
  88. /* read whole pages */
  89. while (len >= EP_PAGE_SIZE) {
  90. read_page(dd, start, buffer);
  91. memcpy(dest, buffer, EP_PAGE_SIZE);
  92. start += EP_PAGE_SIZE;
  93. len -= EP_PAGE_SIZE;
  94. dest += EP_PAGE_SIZE;
  95. }
  96. /* read the last partial page */
  97. if (len) {
  98. read_page(dd, start, buffer);
  99. memcpy(dest, buffer, len);
  100. }
  101. return 0;
  102. }
  103. /*
  104. * Initialize the EPROM handler.
  105. */
  106. int eprom_init(struct hfi1_devdata *dd)
  107. {
  108. int ret = 0;
  109. /* only the discrete chip has an EPROM */
  110. if (dd->pcidev->device != PCI_DEVICE_ID_INTEL0)
  111. return 0;
  112. /*
  113. * It is OK if both HFIs reset the EPROM as long as they don't
  114. * do it at the same time.
  115. */
  116. ret = acquire_chip_resource(dd, CR_EPROM, EPROM_TIMEOUT);
  117. if (ret) {
  118. dd_dev_err(dd,
  119. "%s: unable to acquire EPROM resource, no EPROM support\n",
  120. __func__);
  121. goto done_asic;
  122. }
  123. /* reset EPROM to be sure it is in a good state */
  124. /* set reset */
  125. write_csr(dd, ASIC_EEP_CTL_STAT, ASIC_EEP_CTL_STAT_EP_RESET_SMASK);
  126. /* clear reset, set speed */
  127. write_csr(dd, ASIC_EEP_CTL_STAT,
  128. EP_SPEED_FULL << ASIC_EEP_CTL_STAT_RATE_SPI_SHIFT);
  129. /* wake the device with command "release powerdown NoID" */
  130. write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_RELEASE_POWERDOWN_NOID);
  131. dd->eprom_available = true;
  132. release_chip_resource(dd, CR_EPROM);
  133. done_asic:
  134. return ret;
  135. }
  136. /* magic character sequence that begins an image */
  137. #define IMAGE_START_MAGIC "APO="
  138. /* magic character sequence that might trail an image */
  139. #define IMAGE_TRAIL_MAGIC "egamiAPO"
  140. /* EPROM file types */
  141. #define HFI1_EFT_PLATFORM_CONFIG 2
  142. /* segment size - 128 KiB */
  143. #define SEG_SIZE (128 * 1024)
  144. struct hfi1_eprom_footer {
  145. u32 oprom_size; /* size of the oprom, in bytes */
  146. u16 num_table_entries;
  147. u16 version; /* version of this footer */
  148. u32 magic; /* must be last */
  149. };
  150. struct hfi1_eprom_table_entry {
  151. u32 type; /* file type */
  152. u32 offset; /* file offset from start of EPROM */
  153. u32 size; /* file size, in bytes */
  154. };
  155. /*
  156. * Calculate the max number of table entries that will fit within a directory
  157. * buffer of size 'dir_size'.
  158. */
  159. #define MAX_TABLE_ENTRIES(dir_size) \
  160. (((dir_size) - sizeof(struct hfi1_eprom_footer)) / \
  161. sizeof(struct hfi1_eprom_table_entry))
  162. #define DIRECTORY_SIZE(n) (sizeof(struct hfi1_eprom_footer) + \
  163. (sizeof(struct hfi1_eprom_table_entry) * (n)))
  164. #define MAGIC4(a, b, c, d) ((d) << 24 | (c) << 16 | (b) << 8 | (a))
  165. #define FOOTER_MAGIC MAGIC4('e', 'p', 'r', 'm')
  166. #define FOOTER_VERSION 1
  167. /*
  168. * Read all of partition 1. The actual file is at the front. Adjust
  169. * the returned size if a trailing image magic is found.
  170. */
  171. static int read_partition_platform_config(struct hfi1_devdata *dd, void **data,
  172. u32 *size)
  173. {
  174. void *buffer;
  175. void *p;
  176. u32 length;
  177. int ret;
  178. buffer = kmalloc(P1_SIZE, GFP_KERNEL);
  179. if (!buffer)
  180. return -ENOMEM;
  181. ret = read_length(dd, P1_START, P1_SIZE, buffer);
  182. if (ret) {
  183. kfree(buffer);
  184. return ret;
  185. }
  186. /* config partition is valid only if it starts with IMAGE_START_MAGIC */
  187. if (memcmp(buffer, IMAGE_START_MAGIC, strlen(IMAGE_START_MAGIC))) {
  188. kfree(buffer);
  189. return -ENOENT;
  190. }
  191. /* scan for image magic that may trail the actual data */
  192. p = strnstr(buffer, IMAGE_TRAIL_MAGIC, P1_SIZE);
  193. if (p)
  194. length = p - buffer;
  195. else
  196. length = P1_SIZE;
  197. *data = buffer;
  198. *size = length;
  199. return 0;
  200. }
  201. /*
  202. * The segment magic has been checked. There is a footer and table of
  203. * contents present.
  204. *
  205. * directory is a u32 aligned buffer of size EP_PAGE_SIZE.
  206. */
  207. static int read_segment_platform_config(struct hfi1_devdata *dd,
  208. void *directory, void **data, u32 *size)
  209. {
  210. struct hfi1_eprom_footer *footer;
  211. struct hfi1_eprom_table_entry *table;
  212. struct hfi1_eprom_table_entry *entry;
  213. void *buffer = NULL;
  214. void *table_buffer = NULL;
  215. int ret, i;
  216. u32 directory_size;
  217. u32 seg_base, seg_offset;
  218. u32 bytes_available, ncopied, to_copy;
  219. /* the footer is at the end of the directory */
  220. footer = (struct hfi1_eprom_footer *)
  221. (directory + EP_PAGE_SIZE - sizeof(*footer));
  222. /* make sure the structure version is supported */
  223. if (footer->version != FOOTER_VERSION)
  224. return -EINVAL;
  225. /* oprom size cannot be larger than a segment */
  226. if (footer->oprom_size >= SEG_SIZE)
  227. return -EINVAL;
  228. /* the file table must fit in a segment with the oprom */
  229. if (footer->num_table_entries >
  230. MAX_TABLE_ENTRIES(SEG_SIZE - footer->oprom_size))
  231. return -EINVAL;
  232. /* find the file table start, which precedes the footer */
  233. directory_size = DIRECTORY_SIZE(footer->num_table_entries);
  234. if (directory_size <= EP_PAGE_SIZE) {
  235. /* the file table fits into the directory buffer handed in */
  236. table = (struct hfi1_eprom_table_entry *)
  237. (directory + EP_PAGE_SIZE - directory_size);
  238. } else {
  239. /* need to allocate and read more */
  240. table_buffer = kmalloc(directory_size, GFP_KERNEL);
  241. if (!table_buffer)
  242. return -ENOMEM;
  243. ret = read_length(dd, SEG_SIZE - directory_size,
  244. directory_size, table_buffer);
  245. if (ret)
  246. goto done;
  247. table = table_buffer;
  248. }
  249. /* look for the platform configuration file in the table */
  250. for (entry = NULL, i = 0; i < footer->num_table_entries; i++) {
  251. if (table[i].type == HFI1_EFT_PLATFORM_CONFIG) {
  252. entry = &table[i];
  253. break;
  254. }
  255. }
  256. if (!entry) {
  257. ret = -ENOENT;
  258. goto done;
  259. }
  260. /*
  261. * Sanity check on the configuration file size - it should never
  262. * be larger than 4 KiB.
  263. */
  264. if (entry->size > (4 * 1024)) {
  265. dd_dev_err(dd, "Bad configuration file size 0x%x\n",
  266. entry->size);
  267. ret = -EINVAL;
  268. goto done;
  269. }
  270. /* check for bogus offset and size that wrap when added together */
  271. if (entry->offset + entry->size < entry->offset) {
  272. dd_dev_err(dd,
  273. "Bad configuration file start + size 0x%x+0x%x\n",
  274. entry->offset, entry->size);
  275. ret = -EINVAL;
  276. goto done;
  277. }
  278. /* allocate the buffer to return */
  279. buffer = kmalloc(entry->size, GFP_KERNEL);
  280. if (!buffer) {
  281. ret = -ENOMEM;
  282. goto done;
  283. }
  284. /*
  285. * Extract the file by looping over segments until it is fully read.
  286. */
  287. seg_offset = entry->offset % SEG_SIZE;
  288. seg_base = entry->offset - seg_offset;
  289. ncopied = 0;
  290. while (ncopied < entry->size) {
  291. /* calculate data bytes available in this segment */
  292. /* start with the bytes from the current offset to the end */
  293. bytes_available = SEG_SIZE - seg_offset;
  294. /* subtract off footer and table from segment 0 */
  295. if (seg_base == 0) {
  296. /*
  297. * Sanity check: should not have a starting point
  298. * at or within the directory.
  299. */
  300. if (bytes_available <= directory_size) {
  301. dd_dev_err(dd,
  302. "Bad configuration file - offset 0x%x within footer+table\n",
  303. entry->offset);
  304. ret = -EINVAL;
  305. goto done;
  306. }
  307. bytes_available -= directory_size;
  308. }
  309. /* calculate bytes wanted */
  310. to_copy = entry->size - ncopied;
  311. /* max out at the available bytes in this segment */
  312. if (to_copy > bytes_available)
  313. to_copy = bytes_available;
  314. /*
  315. * Read from the EPROM.
  316. *
  317. * The sanity check for entry->offset is done in read_length().
  318. * The EPROM offset is validated against what the hardware
  319. * addressing supports. In addition, if the offset is larger
  320. * than the actual EPROM, it silently wraps. It will work
  321. * fine, though the reader may not get what they expected
  322. * from the EPROM.
  323. */
  324. ret = read_length(dd, seg_base + seg_offset, to_copy,
  325. buffer + ncopied);
  326. if (ret)
  327. goto done;
  328. ncopied += to_copy;
  329. /* set up for next segment */
  330. seg_offset = footer->oprom_size;
  331. seg_base += SEG_SIZE;
  332. }
  333. /* success */
  334. ret = 0;
  335. *data = buffer;
  336. *size = entry->size;
  337. done:
  338. kfree(table_buffer);
  339. if (ret)
  340. kfree(buffer);
  341. return ret;
  342. }
  343. /*
  344. * Read the platform configuration file from the EPROM.
  345. *
  346. * On success, an allocated buffer containing the data and its size are
  347. * returned. It is up to the caller to free this buffer.
  348. *
  349. * Return value:
  350. * 0 - success
  351. * -ENXIO - no EPROM is available
  352. * -EBUSY - not able to acquire access to the EPROM
  353. * -ENOENT - no recognizable file written
  354. * -ENOMEM - buffer could not be allocated
  355. * -EINVAL - invalid EPROM contentents found
  356. */
  357. int eprom_read_platform_config(struct hfi1_devdata *dd, void **data, u32 *size)
  358. {
  359. u32 directory[EP_PAGE_DWORDS]; /* aligned buffer */
  360. int ret;
  361. if (!dd->eprom_available)
  362. return -ENXIO;
  363. ret = acquire_chip_resource(dd, CR_EPROM, EPROM_TIMEOUT);
  364. if (ret)
  365. return -EBUSY;
  366. /* read the last page of the segment for the EPROM format magic */
  367. ret = read_length(dd, SEG_SIZE - EP_PAGE_SIZE, EP_PAGE_SIZE, directory);
  368. if (ret)
  369. goto done;
  370. /* last dword of the segment contains a magic value */
  371. if (directory[EP_PAGE_DWORDS - 1] == FOOTER_MAGIC) {
  372. /* segment format */
  373. ret = read_segment_platform_config(dd, directory, data, size);
  374. } else {
  375. /* partition format */
  376. ret = read_partition_platform_config(dd, data, size);
  377. }
  378. done:
  379. release_chip_resource(dd, CR_EPROM);
  380. return ret;
  381. }