2
0

romcopy.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. #include "fw.h"
  2. #include "console.h"
  3. #include "io.h"
  4. #include "spiflash.h"
  5. enum romcmd {
  6. ROM_WRITE_ENABLE = 0x06,
  7. ROM_VOLATILE_SR_WRITE_ENABLE = 0x50,
  8. ROM_WRITE_DISABLE = 0x04,
  9. ROM_RELEASE_POWERDOWN_ID = 0xab,
  10. ROM_MANUFACTURER_DEVICE_ID = 0x90,
  11. ROM_JEDEC_ID = 0x9f,
  12. ROM_READ_UNIQUE_ID = 0x4b,
  13. ROM_READ_DATA = 0x03, /* DO NOT USE */
  14. ROM_FAST_READ = 0x0b,
  15. ROM_PAGE_PROGRAM = 0x02,
  16. ROM_ERASE_4K = 0x20,
  17. ROM_ERASE_32K = 0x52,
  18. ROM_ERASE_64K = 0xd8,
  19. ROM_ERASE_ALL = 0xc7,
  20. ROM_READ_SR1 = 0x05,
  21. ROM_WRITE_SR1 = 0x01,
  22. ROM_READ_SR2 = 0x35,
  23. ROM_WRITE_SR2 = 0x31,
  24. ROM_READ_SR3 = 0x15,
  25. ROM_WRITE_SR3 = 0x11,
  26. ROM_READ_SFPD = 0x5a,
  27. ROM_ERASE_SECURITY = 0x44,
  28. ROM_PROGRAM_SECURITY = 0x42,
  29. ROM_READ_SECURITY = 0x48,
  30. ROM_GLOBAL_BLOCK_LOCK = 0x7e,
  31. ROM_GLOBAL_BLOCK_UNLOCK = 0x98,
  32. ROM_READ_BLOCK_LOCK = 0x3d,
  33. ROM_ONE_BLOCK_LOCK = 0x36,
  34. ROM_ONE_BLOCK_UNLOCK = 0x39,
  35. ROM_ERASE_PROGRAM_SUSPEND = 0x75,
  36. ROM_ERASE_PROGRAM_RESUME = 0x7a,
  37. ROM_POWER_DOWN = 0xb9,
  38. ROM_ENABLE_RESET = 0x66,
  39. ROM_RESET = 0x99,
  40. ROM_FAST_READ_DUAL = 0x3b
  41. };
  42. #define SPIROM_DUAL_MODE 1
  43. void __hot romcopy_download(void *dst, size_t offset, size_t len)
  44. {
  45. unsigned int cmd;
  46. unsigned int flags = ROMCOPY_SPI_CMDLEN(5) | ROMCOPY_WRITE_RAM;
  47. if (SPIROM_DUAL_MODE) {
  48. cmd = ROM_FAST_READ_DUAL;
  49. flags |= ROMCOPY_SPI_DUAL;
  50. } else {
  51. cmd = ROM_FAST_READ;
  52. }
  53. ROMCOPY_RAMADDR = (size_t)dst;
  54. ROMCOPY_ROMCMD = __rom_offset + offset + (cmd << 24);
  55. ROMCOPY_DATALEN = len | flags;
  56. }
  57. void __hot romcopy_bzero(void *dst, size_t len)
  58. {
  59. ROMCOPY_RAMADDR = (size_t)dst;
  60. ROMCOPY_ROMCMD = 0;
  61. ROMCOPY_DATALEN = len | ROMCOPY_ZERO_BUFFER | ROMCOPY_WRITE_RAM;
  62. }
  63. /*
  64. * Read unique serial number programmed into ROM
  65. *
  66. */
  67. char __bss_hot rom_serial_str[16];
  68. qword_t __bss_hot rom_serial;
  69. static __must_inline void rom_read_serial(void)
  70. {
  71. ROMCOPY_ROMCMD = ROM_READ_UNIQUE_ID << 24;
  72. ROMCOPY_DATALEN = ROMCOPY_SPI_CMDLEN(5) | ROMCOPY_SPI_MORE;
  73. waitfor(ROMCOPY_IRQ);
  74. ROMCOPY_DATALEN = ROMCOPY_SPI_CMDLEN(4) | ROMCOPY_SPI_MORE;
  75. waitfor(ROMCOPY_IRQ);
  76. rom_serial.l[1] = ROMCOPY_INPUT;
  77. ROMCOPY_DATALEN = ROMCOPY_SPI_CMDLEN(4);
  78. waitfor(ROMCOPY_IRQ);
  79. rom_serial.l[0] = ROMCOPY_INPUT;
  80. }
  81. /*
  82. * Convert the ROM serial number to a hex string and poke it into the
  83. * USB descriptor "ROM". Used to use base36, but this has to be done
  84. * very early, and it has turned out that making it consistent with
  85. * what one can easily get out of a debugger is really useful.
  86. *
  87. * Doing this as early as possible means a much better chance to see
  88. * the proper serial number during USB enumeration, so doing it
  89. * immediately after SPI ROM conditioning is a great time.
  90. */
  91. static __must_inline void rom_mangle_serial(void)
  92. {
  93. volatile uint32_t *udp = &usbdesc_rom[2];
  94. for (int i = 7; i >= 0; i--) {
  95. unsigned int v = rom_serial.b[i];
  96. unsigned int c;
  97. c = (v >> 4)+'0';
  98. if (c > '9')
  99. c += 'A'-'9'-1;
  100. udp[0] = c;
  101. c = (v & 15)+'0';
  102. if (c > '9')
  103. c += 'A'-'9'-1;
  104. udp[2] = c;
  105. udp += 4;
  106. }
  107. }
  108. void rom_print_serial(void)
  109. {
  110. /* Print the ROM serial when we actually can */
  111. con_printf("ROM serial: %08X%08X (%08x-%08x)\n",
  112. rom_serial.l[1], rom_serial.l[0],
  113. rom_serial.l[1], rom_serial.l[0]);
  114. }
  115. static __must_inline void romcopy_config_flash(void)
  116. {
  117. /* Enable writing volatile status register bits */
  118. ROMCOPY_ROMCMD = ROM_VOLATILE_SR_WRITE_ENABLE << 24;
  119. ROMCOPY_DATALEN = ROMCOPY_SPI_CMDLEN(1);
  120. waitfor(ROMCOPY_IRQ);
  121. /* Write SR3 = 0; this sets the drive strength to maximum */
  122. ROMCOPY_ROMCMD = ROM_WRITE_SR3 << 24;
  123. ROMCOPY_DATALEN = ROMCOPY_SPI_CMDLEN(2);
  124. waitfor(ROMCOPY_IRQ);
  125. }
  126. IRQHANDLER(romcopy,0)
  127. {
  128. static __sbss unsigned int romcopy_state;
  129. size_t len;
  130. switch (romcopy_state++) {
  131. case 0:
  132. /* Condition flash ROM */
  133. romcopy_config_flash();
  134. /* Read serial number */
  135. rom_read_serial();
  136. /* Start copy DRAM data */
  137. len = __dram_init_end - __dram_init_start;
  138. romcopy_download(__dram_init_start, 0, len);
  139. /* Convert serial number and export to USB */
  140. rom_mangle_serial();
  141. break;
  142. case 1:
  143. /* Zero .dram.bss */
  144. len = __dram_bss_end - __dram_bss_start;
  145. romcopy_bzero(__dram_bss_start, len);
  146. break;
  147. default:
  148. mask_irq(ROMCOPY_IRQ);
  149. break;
  150. }
  151. }
  152. /*
  153. * SPI flash parameters and routines (for spiflash.c)
  154. */
  155. static const struct spiflash_ops max80_spiflash_ops;
  156. static const struct spiflash_param max80_spiflash_param;
  157. /*
  158. * SPI flash operations
  159. */
  160. static int max80_spi_write_buffer(const void *buf, unsigned int buflen,
  161. bool more)
  162. {
  163. const uint8_t *p = buf;
  164. uint32_t cmd = 0;
  165. unsigned int bytecmd = 0;
  166. while (buflen) {
  167. cmd = (*p++ << 24) | (cmd >> 8);
  168. buflen--;
  169. bytecmd += ROMCOPY_SPI_CMDLEN(1);
  170. if (!(buflen & 3)) {
  171. if (buflen || more)
  172. bytecmd |= ROMCOPY_SPI_MORE;
  173. waitfor(ROMCOPY_IRQ);
  174. ROMCOPY_ROMCMD = cmd;
  175. ROMCOPY_DATALEN = bytecmd;
  176. bytecmd = cmd = 0;
  177. }
  178. }
  179. return 0;
  180. }
  181. static int max80_spi_read_buffer(void *buf, unsigned int buflen, bool more)
  182. {
  183. uint8_t *p = buf;
  184. unsigned int bytecmd;
  185. uint32_t v;
  186. if (!buflen)
  187. return 0;
  188. waitfor(ROMCOPY_IRQ);
  189. ROMCOPY_ROMCMD = 0;
  190. while (buflen > 4) {
  191. ROMCOPY_DATALEN = ROMCOPY_SPI_CMDLEN(4) | ROMCOPY_SPI_MORE;
  192. waitfor(ROMCOPY_IRQ);
  193. v = ROMCOPY_INPUT;
  194. p[0] = v >> 24;
  195. p[1] = v >> 16;
  196. p[2] = v >> 8;
  197. p[3] = v;
  198. p += 4;
  199. buflen -= 4;
  200. }
  201. bytecmd = ROMCOPY_SPI_CMDLEN(buflen);
  202. if (more)
  203. bytecmd |= ROMCOPY_SPI_MORE;
  204. ROMCOPY_DATALEN = bytecmd;
  205. waitfor(ROMCOPY_IRQ);
  206. v = ROMCOPY_INPUT;
  207. v <<= ((4-buflen) << 3);
  208. while (buflen--) {
  209. *p++ = v >> 24;
  210. v <<= 8;
  211. }
  212. return 0;
  213. }
  214. static int max80_spi_write(void *cookie,
  215. const void *cmd, unsigned int cmd_len,
  216. const void *data, unsigned int data_len,
  217. int tshsl)
  218. {
  219. (void)cookie;
  220. (void)tshsl; /* Enforced in hardware */
  221. if (cmd_len)
  222. max80_spi_write_buffer(cmd, cmd_len, !!data_len);
  223. if (data_len)
  224. max80_spi_write_buffer(data, data_len, false);
  225. return 0;
  226. }
  227. static int max80_spi_read(void *cookie,
  228. const void *cmd, unsigned int cmd_len,
  229. void *data, unsigned int data_len,
  230. int tshsl)
  231. {
  232. (void)cookie;
  233. (void)tshsl; /* Enforced in hardware */
  234. if (cmd_len)
  235. max80_spi_write_buffer(cmd, cmd_len, !!data_len);
  236. if (data_len)
  237. max80_spi_read_buffer(data, data_len, false);
  238. return 0;
  239. }
  240. static const struct spiflash_ops max80_spiflash_ops = {
  241. .read_data = NULL, /* From memory buffer */
  242. .close_data = NULL, /* Nothing to do */
  243. .spi_write = max80_spi_write,
  244. .spi_read = max80_spi_read,
  245. .yield = NULL /* Nothing to yield to... */
  246. };
  247. /* Winbond W25Q128JV @ 3.3V */
  248. #define NS(x) (((x)*(unsigned long long)CPU_HZ + 999999999ULL)/1000000000ULL)
  249. #define US(x) (((x)*(unsigned long long)CPU_HZ + 999999ULL)/1000000ULL)
  250. #define MS(x) (((x)*(unsigned long long)CPU_HZ + 999ULL)/1000ULL)
  251. static const struct spiflash_param max80_spiflash_param = {
  252. /*
  253. * For W25Q128JV _DYNAMIC is equivalent to _24BIT, but specifying
  254. * it as dynamic would most of the time support larger parts
  255. * transparently.
  256. */
  257. .addr = SPIFLASH_ADDR_DYNAMIC,
  258. .tshsl = NS(3),
  259. .tshsl1 = NS(10),
  260. .tshsl2 = NS(50),
  261. .trst = NS(30000),
  262. .tw = MS(10), /* persistent; typ, max = 15 */
  263. .tpp = NS(400), /* typ, max = 3000 */
  264. .tse = MS(45), /* typ, max = 400 */
  265. .tbe1 = MS(120), /* typ, max = 1600 */
  266. .tbe2 = MS(150), /* typ, max = 2000 */
  267. .tce = MS(40000), /* typ, max = 200000 */
  268. };
  269. static struct spiflash max80_flash = {
  270. .ops = &max80_spiflash_ops,
  271. .cookie = NULL,
  272. .param = &max80_spiflash_param
  273. };
  274. /*
  275. * Flash an image into SPI flash, and reload the FPGA if successful,
  276. * returns on failure only.
  277. */
  278. void rom_flash_from_memory(void *buf, size_t buflen)
  279. {
  280. const struct spiflash_header *hdr = buf;
  281. if (hdr->magic != SPIFLASH_MAGIC)
  282. return;
  283. if (hdr->magic != SPIFLASH_MAGIC ||
  284. spiflash_flash_files(&max80_flash, buf, buflen)) {
  285. con_puts("update: flash update data invalid\n");
  286. return;
  287. }
  288. con_puts("update: Flash complete, restarting in 5 s...\n");
  289. udelay(5000000);
  290. reset(SYS_RESET_RECONFIG);
  291. }