flash_test_main.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /* Copyright (C) 2017 RDA Technologies Limited and/or its affiliates("RDA").
  2. * All rights reserved.
  3. *
  4. * This software is supplied "AS IS" without any warranties.
  5. * RDA assumes no responsibility or liability for the use of the software,
  6. * conveys no license or title under any patent, copyright, or mask work
  7. * right to the product. RDA reserves the right to make changes in the
  8. * software without notification. RDA also make no representation or
  9. * warranty that such application will be suitable for the specified use
  10. * without further testing or modification.
  11. */
  12. // #define LOCAL_LOG_LEVEL LOG_LEVEL_DEBUG
  13. #include "boot_fdl.h"
  14. #include "boot_entry.h"
  15. #include "boot_platform.h"
  16. #include "boot_debuguart.h"
  17. #include "boot_mem.h"
  18. #include "boot_spi_flash.h"
  19. #include "boot_bsl_cmd.h"
  20. #include "hal_chip.h"
  21. #include "hal_config.h"
  22. #include "hal_spi_flash.h"
  23. #include "hal_adi_bus.h"
  24. #include "cmsis_core.h"
  25. #include "osi_log.h"
  26. #include "osi_api.h"
  27. #include "drv_names.h"
  28. #include <sys/reent.h>
  29. #include <stdint.h>
  30. #include <string.h>
  31. #include <machine/endian.h>
  32. #define FDL_SIZE_4K (0x1000)
  33. #define FDL_SIZE_32K (0x8000)
  34. #define FDL_SIZE_64K (0x10000)
  35. #define ALIGN_SIZE(v, a) (((v) & ~((a)-1)) == 0 ? 1 : 0)
  36. #define FLASH_TEST_ACK 0xD0
  37. #define FLASH_TEST_ERR 0xD1
  38. #define PATTERN_LEN 4096
  39. uint32_t test_cnt;
  40. static uint8_t pattern[PATTERN_LEN];
  41. struct flashtest_time
  42. {
  43. uint32_t erase;
  44. uint32_t write;
  45. };
  46. typedef struct flashtest_time flashtest_time_t;
  47. static void _arrayValueInit(void)
  48. {
  49. uint16_t arr_len = PATTERN_LEN;
  50. uint16_t val_len = 64;
  51. uint8_t values[] = {0xa, 0x5, 0xa, 0x5, 0xa, 0x5, 0xa, 0x5, 0x5, 0xa, 0x5, 0xa, 0x5, 0xa, 0x5, 0xa,
  52. 0x0, 0x0, 0x0, 0x0, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0, 0x0, 0x0, 0x0,
  53. 0xf, 0xf, 0x0, 0x0, 0xf, 0xf, 0x0, 0x0, 0x0, 0x0, 0xf, 0xf, 0x0, 0x0, 0xf, 0xf,
  54. 0xf, 0x0, 0xf, 0x0, 0xf, 0x0, 0xf, 0x0, 0x0, 0xf, 0x0, 0xf, 0x0, 0xf, 0x0, 0xf};
  55. int i = 0;
  56. while (i < arr_len)
  57. {
  58. memcpy(&pattern[i], values, val_len);
  59. i += val_len;
  60. }
  61. OSI_LOGI(0x10009096, "FLASH: init pattern %x %x %x ... %x %x %x", pattern[0], pattern[1], pattern[2], pattern[4093], pattern[4094], pattern[4095]);
  62. }
  63. static bool _bootFlashChipErase(bootSpiFlash_t *flash)
  64. {
  65. bootSpiFlashChipErase(flash);
  66. uint8_t *rd_data = (uint8_t *)bootSpiFlashMapAddress(flash, 0);
  67. uint32_t rd_size = bootSpiFlashCapacity(flash);
  68. while (rd_size > 0)
  69. {
  70. if (*(rd_data++) != 0xff)
  71. {
  72. OSI_LOGE(0x10009097, "FLASH: Erase whole flash error2 0x%x != 0xff...", rd_data);
  73. return false;
  74. }
  75. rd_size--;
  76. }
  77. return true;
  78. }
  79. static bool _bootFlashErase(bootSpiFlash_t *flash, uint32_t offset, size_t size, size_t sector)
  80. {
  81. bool res = false;
  82. switch (sector)
  83. {
  84. case FDL_SIZE_4K:
  85. case FDL_SIZE_32K:
  86. case FDL_SIZE_64K:
  87. res = bootSpiFlashErase(flash, offset, size);
  88. break;
  89. default:
  90. OSI_LOGE(0x10009098, "FLASH: sector invalid 0x%x", sector);
  91. }
  92. return res;
  93. }
  94. static bool _bootFlashWrite(bootSpiFlash_t *flash, uint32_t offset, size_t size)
  95. {
  96. uint32_t len = PATTERN_LEN;
  97. uint32_t wr_addr = offset;
  98. uint32_t wr_size = size;
  99. while (wr_size > 0)
  100. {
  101. if (!bootSpiFlashWrite(flash, wr_addr, &pattern[0], len))
  102. {
  103. OSI_LOGE(0x10009099, "FLASH: Write flash error offset %x", wr_addr);
  104. return false;
  105. }
  106. wr_addr += len;
  107. wr_size -= len;
  108. }
  109. // check write ok
  110. uint32_t rd_size = size;
  111. const void *fdata = bootSpiFlashMapAddress(flash, offset);
  112. uint8_t *rd_data = (uint8_t *)fdata;
  113. while (rd_size > 0)
  114. {
  115. for (int i = 0; i < len; i++)
  116. {
  117. if (*(rd_data + i) != pattern[i])
  118. {
  119. OSI_LOGE(0x1000909a, "FLASH: Check write flash error %x shoule be %x", *(rd_data + i), pattern[i]);
  120. return false;
  121. }
  122. }
  123. rd_data += len;
  124. rd_size -= len;
  125. }
  126. return true;
  127. }
  128. static void flashEraseWriteStart(fdlEngine_t *fdl, fdlPacket_t *pkt, bootSpiFlash_t *flash)
  129. {
  130. uint32_t *ptr = (uint32_t *)pkt->content;
  131. uint32_t offset = __ntohl(*ptr++);
  132. uint32_t test_size = __ntohl(*ptr++);
  133. uint32_t sector_size = __ntohl(*ptr++);
  134. flashtest_time_t flash_time = {};
  135. osiElapsedTimer_t elapsed;
  136. OSI_LOGI(0x1000909b, "FLASH: offset 0x%x, size 0x%x sector 0x%x...", offset, test_size, sector_size);
  137. if (!offset && !test_size)
  138. {
  139. osiElapsedTimerStart(&elapsed);
  140. if (!_bootFlashChipErase(flash))
  141. {
  142. OSI_LOGE(0x1000909c, "FLASH: erase whole flash fail");
  143. const char erase_string[] = "Erase whole flash fail";
  144. size_t er_len = strlen(erase_string);
  145. fdlEngineSendRespData(fdl, FLASH_TEST_ERR, erase_string, er_len);
  146. osiPanic();
  147. }
  148. flash_time.erase = osiElapsedTime(&elapsed);
  149. flash_time.write = 0;
  150. OSI_LOGI(0x1000909d, "FLASH: erase whole flash time %d, use %d ms ...", ++test_cnt, flash_time.erase);
  151. }
  152. else
  153. {
  154. if (!bootSpiFlashOffsetValid(flash, offset) ||
  155. !bootSpiFlashOffsetValid(flash, offset + test_size - 1))
  156. {
  157. OSI_LOGE(0x1000909e, "FLASH: addr and size invalid");
  158. // send cmd err
  159. const char cmd_string[] = "Cmd addr or size invalid";
  160. size_t cmd_len = strlen(cmd_string);
  161. fdlEngineSendRespData(fdl, FLASH_TEST_ERR, cmd_string, cmd_len);
  162. }
  163. OSI_LOGI(0x1000909f, "start test flash...");
  164. // erase flash test
  165. osiElapsedTimerStart(&elapsed);
  166. if (!_bootFlashErase(flash, offset, test_size, sector_size))
  167. {
  168. OSI_LOGE(0x100090a0, "FLASH: erase flash error");
  169. const char sector_string[] = "Erase sector flash fail";
  170. size_t sec_len = strlen(sector_string);
  171. fdlEngineSendRespData(fdl, FLASH_TEST_ERR, sector_string, sec_len);
  172. osiPanic();
  173. }
  174. flash_time.erase = osiElapsedTime(&elapsed);
  175. // write flash test
  176. osiElapsedTimerStart(&elapsed);
  177. if (!_bootFlashWrite(flash, offset, test_size))
  178. {
  179. OSI_LOGE(0x100090a1, "FLASH: write flash error");
  180. const char wr_string[] = "Write sector flash fail";
  181. size_t wr_len = strlen(wr_string);
  182. fdlEngineSendRespData(fdl, FLASH_TEST_ERR, wr_string, wr_len);
  183. osiPanic();
  184. }
  185. flash_time.write = osiElapsedTime(&elapsed);
  186. OSI_LOGI(0x100090a2, "FLASH:time %d erase/write ~~~ %d ms / %d ms...", ++test_cnt, flash_time.erase, flash_time.write);
  187. }
  188. fdlEngineSendRespData(fdl, FLASH_TEST_ACK, &flash_time, sizeof(flashtest_time_t));
  189. }
  190. static void _process_flash(fdlEngine_t *fdl, fdlPacket_t *pkt, void *flash_)
  191. {
  192. if (fdl == NULL || pkt == NULL)
  193. osiPanic();
  194. bootSpiFlash_t *flash = (bootSpiFlash_t *)flash_;
  195. switch (pkt->type)
  196. {
  197. case BSL_CMD_CONNECT:
  198. fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
  199. break;
  200. case BSL_CMD_ERASE_FLASH:
  201. flashEraseWriteStart(fdl, pkt, flash);
  202. break;
  203. default:
  204. OSI_LOGE(0x1000908e, "FDL1, cmd not support yet %x", pkt->type);
  205. osiPanic();
  206. break;
  207. }
  208. }
  209. void bootStart(uint32_t param)
  210. {
  211. OSI_CLEAR_SECTION(bss);
  212. halClockInit(HAL_CLOCK_INIT_FDL);
  213. __FPU_Enable();
  214. _impure_ptr = _GLOBAL_REENT;
  215. bootTraceInit(true);
  216. halAdiBusInit();
  217. extern unsigned __sram_heap_start[];
  218. extern unsigned __sram_heap_end[];
  219. unsigned sram_heap_size = OSI_PTR_DIFF(__sram_heap_end, __sram_heap_start);
  220. bootHeapInit((uint32_t *)__sram_heap_start, sram_heap_size, 0, 0);
  221. OSI_LOGI(0x100090a3, "FLASH_TEST_RUN ......");
  222. fdlChannel_t *ch = fdlOpenUart(CONFIG_FDL_DEFAULT_UART, CONFIG_FDL_UART_BAUD, true);
  223. if (ch == NULL)
  224. {
  225. OSI_LOGE(0x100090a4, "FDL1 fail, can't open uart fdl channel");
  226. osiPanic();
  227. }
  228. fdlEngine_t *fdl = fdlEngineCreate(ch, CONFIG_FDL_PACKET_MAX_LEN);
  229. if (fdl == NULL)
  230. {
  231. OSI_LOGE(0x100090a5, "FDL1 fail, can not create fdl engine");
  232. osiPanic();
  233. }
  234. for (;;)
  235. {
  236. uint8_t sync;
  237. if (fdlEngineReadRaw(fdl, &sync, 1))
  238. {
  239. if (sync == HDLC_FLAG)
  240. {
  241. if (!fdlEngineSendVersion(fdl))
  242. {
  243. OSI_LOGE(0x100090a6, "FDL1 fail, fail to send version string");
  244. osiPanic();
  245. }
  246. break;
  247. }
  248. }
  249. }
  250. _arrayValueInit();
  251. bootSpiFlash_t *flash = bootSpiFlashOpen(DRV_NAME_SPI_FLASH);
  252. fdlEngineProcess(fdl, _process_flash, NULL, flash);
  253. // never return here
  254. fdlEngineDestroy(fdl);
  255. osiPanic();
  256. }