boot_fdl_dnld_8910.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518
  1. /* Copyright (C) 2019 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 OSI_LOCAL_LOG_TAG OSI_MAKE_LOG_TAG('F', 'D', 'L', 'D')
  13. // #define OSI_LOCAL_LOG_LEVEL OSI_LOG_LEVEL_DEBUG
  14. #include "boot_fdl.h"
  15. #include "boot_platform.h"
  16. #include "boot_spi_flash.h"
  17. #include "hal_chip.h"
  18. #include "boot_secure.h"
  19. #include "boot_bsl_cmd.h"
  20. #include "hal_config.h"
  21. #include "osi_log.h"
  22. #include "osi_api.h"
  23. #include "drv_names.h"
  24. #include "fs_mount.h"
  25. #include "vfs.h"
  26. #include "nvm.h"
  27. #include "calclib/crc32.h"
  28. #include "calclib/sha256.h"
  29. #include "calclib/simage.h"
  30. #include "cpio_parser.h"
  31. #include <stdint.h>
  32. #include <string.h>
  33. #include <stdlib.h>
  34. #include <assert.h>
  35. #include "quec_boot_log.h"
  36. #include "quec_cust_patch.h"
  37. #include "quec_proj_config.h"
  38. #include "quec_boot_file_cfg.h"
  39. #ifdef CONFIG_QUEC_PROJECT_FEATURE
  40. #include "fupdate_config.h"
  41. #endif
  42. #ifdef CONFIG_QUEC_PROJECT_FEATURE_BOOT_SPI4_EXTNSFFS
  43. #include "fs_mount_spiflash.h"
  44. #include "ql_boot_spi4_exnsffs_cfg.h"
  45. #endif
  46. #ifdef CONFIG_QUEC_PROJECT_FEATURE_BOOT_FAT_RW
  47. #include "fs_config.h"
  48. #include "quec_boot_pff.h"
  49. #if (defined CONFIG_QUEC_PROJECT_FEATURE_BOOT_SDMMC) || (defined CONFIG_QUEC_PROJECT_FEATURE_BOOT_EMMC)
  50. #include "quec_boot_sdmmc.h"
  51. #include "drv_sdmmc_imp.h"
  52. extern ql_boot_sdmmc_cfg_t ql_boot_sdmmc_cfg; //sdmmc配置
  53. #endif
  54. #endif
  55. // Work memory size in context
  56. #define WORKMEM_SIZE (CONFIG_NVBIN_FIXED_SIZE < 0x10000 ? 0x10000 : CONFIG_NVBIN_FIXED_SIZE)
  57. #ifdef __QUEC_OEM_VER_TY__
  58. #define PACKAGE_FILE_MAX_SIZE 0x100000
  59. #else
  60. #ifdef CONFIG_QUEC_PROJECT_FEATURE
  61. #define PACKAGE_FILE_MAX_SIZE 0x180000
  62. #else
  63. #define PACKAGE_FILE_MAX_SIZE 0x10000
  64. #endif
  65. #endif
  66. #ifdef CONFIG_QUEC_PROJECT_FEATURE
  67. #define TTS_PREPACK_FILE_PATH "/qsfs/quectel_pcm_resource.bin"
  68. #define TTS_EN_PREPACK_FILE_PATH "/qsfs/quectel_pcm_english.bin"
  69. #define GNSS_BOOT_FILE_PATH "/user/boot"
  70. #define GNSS_FIRM_FILE_PATH "/user/firm"
  71. #define QL_TTS_RESOURCE_APPEND_BIN "/qsfs/quectel_pcm_resource_append.bin"
  72. #define QL_TTS_RESOURCE_END_BIN "/qsfs/quectel_pcm_resource_ff.bin"
  73. #define QL_TTS_RESOURCE_PACKET_MAX 10
  74. #endif
  75. // Logic addresses, which should match the value used in pac file
  76. #define ERASE_RUNNING_NV_LOGIC_ADDRESS 0xFE000001
  77. #define PHASECHECK_LOGIC_ADDRESS 0xFE000002
  78. #define FIXNV_LOGIC_ADDRESS 0xFE000003
  79. #define PRE_PACK_FILE_LOGIC_ADDRESS 0xFE000004
  80. #define DEL_APPIMG_LOGIC_ADDRESS 0xFE000005
  81. #define FMT_FLASH_LOGIC_ADDRESS 0xFE000006
  82. #define FLASH_ERASE_ALL 0x00000000
  83. #define FLASH_ERASE_ALL_SIZE 0xFFFFFFFF
  84. #define FLASH_PAGE_SIZE (256)
  85. #define FLASH_SECTOR_SIZE (0x1000)
  86. #define FDL_SIZE_4K (0x1000)
  87. // 8910 encrypt
  88. #define BOOT_SIGN_SIZE (0xbd40)
  89. #define ENCRYPT_OFF 0x1000
  90. #define ENCRYPT_LEN 0x400
  91. #define DELAY_POWEROFF_TIMEOUT (2000)
  92. #define ERR_REP_RETURN(fdl, err) OSI_DO_WHILE0(fdlEngineSendRespNoData(fdl, err); return;)
  93. #if (defined CONFIG_BOARD_WITH_EXT_FLASH) || (defined CONFIG_QUEC_PROJECT_FEATURE_SPI6_EXT_NOR)
  94. #define IS_FLASH_ADDRESS(address) (HAL_FLASH_DEVICE_NAME(address) == DRV_NAME_SPI_FLASH || HAL_FLASH_DEVICE_NAME(address) == DRV_NAME_SPI_FLASH_EXT)
  95. #else /*#ifndef CONFIG_BOARD_WITH_EXT_FLASH*/
  96. #define IS_FLASH_ADDRESS(address) (HAL_FLASH_DEVICE_NAME(address) == DRV_NAME_SPI_FLASH)
  97. #endif/*CONFIG_BOARD_WITH_EXT_FLASH*/
  98. #ifdef QUEC_PATCH_FACTORY_UPDATE
  99. bool g_upgrade_by_factory = false;
  100. #endif
  101. enum
  102. {
  103. FS_PREPARE_WRITE_PHASECHEK,
  104. FS_PREPARE_WRITE_FIXEDNV,
  105. FS_PREPARE_WRITE_PREPACK,
  106. FS_PREPARE_READ_PHASECHECK,
  107. FS_PREPARE_READ_FIXEDNV,
  108. FS_PREPARE_ERASE_RUNNINGNV,
  109. FS_PREPARE_ERASE_PHASECHECK,
  110. FS_PREPARE_ERASE_APPIMG_FILE,
  111. FS_PREPARE_BACKUP_PHASE_CHECK,
  112. };
  113. typedef struct
  114. {
  115. cpioStream_t *cpio;
  116. fdlDataDnld_t dnld;
  117. bool running_cleared;
  118. bool phasecheck_backed;
  119. bool fixednv_backed;
  120. unsigned init_nvbin_size;
  121. unsigned init_nvbin_crc;
  122. bool secure_boot_enable;
  123. bool delay_poweroff;
  124. bool flash_write_whole;
  125. unsigned device_type;
  126. fdlChannel_t *channel;
  127. unsigned max_packet_len;
  128. osiElapsedTimer_t connect_timer;
  129. phaseCheckHead_t phasecheck_back;
  130. char fixednv_back[CONFIG_NVBIN_FIXED_SIZE];
  131. char work_mem[WORKMEM_SIZE];
  132. char *flash_mem;
  133. } fdlContext_t;
  134. /**
  135. * When needed, hacks for nv on factory partition
  136. */
  137. static bool prvFactoryNvHack(fdlContext_t *d)
  138. {
  139. #ifdef CONFIG_SOC_8910
  140. // HACK: ResearchDownload needs that nvid 2 must exist, and
  141. // previously this nv isn't added in 8910. Due to this nv isn't actually
  142. // used. So, at the beginning of FDL2, this will be written to make
  143. // ResearchDownload happy.
  144. if (nvmReadItem(NVID_CALIB_PARAM, NULL, 0) <= 0)
  145. {
  146. // Refer to CMakeLists.txt about these 2 external symbols.
  147. extern const unsigned gDefCalibParam[];
  148. extern const unsigned gDefCalibParamSize[];
  149. nvmWriteItem(NVID_CALIB_PARAM, gDefCalibParam, (unsigned)gDefCalibParamSize);
  150. }
  151. // HACK: GSM calibration data size is changed from 7706 to 8192. The
  152. // size of existed GSM calibration data may be 7706. And it is needed
  153. // to pad the existed GSM calibration data to 8192, to make NVEditor
  154. // work, and make nv backup work.
  155. int calib_gsm_size = nvmReadFixedItem(0x26d, NULL, 0);
  156. if (calib_gsm_size > 0 && calib_gsm_size < 8192)
  157. {
  158. char *calib_gsm_bin = &d->work_mem[0];
  159. memset(calib_gsm_bin, 0, 8192);
  160. nvmReadFixedItem(0x26d, calib_gsm_bin, 8192);
  161. nvmWriteFixedItem(0x26d, calib_gsm_bin, 8192);
  162. }
  163. #endif
  164. return true;
  165. }
  166. /**
  167. * Mount factory partition
  168. */
  169. static bool prvMountFactory(fdlContext_t *d)
  170. {
  171. if (!fsMountFsPath(CONFIG_FS_FACTORY_MOUNT_POINT, false))
  172. return false;
  173. return prvFactoryNvHack(d);
  174. }
  175. /**
  176. * Mount factory partition, and format on fail
  177. */
  178. static bool prvMountFormatFactory(fdlContext_t *d)
  179. {
  180. if (!fsMountFsPath(CONFIG_FS_FACTORY_MOUNT_POINT, true))
  181. return false;
  182. return prvFactoryNvHack(d);
  183. }
  184. /**
  185. * Mount modem partition
  186. */
  187. static bool prvMountModem(fdlContext_t *d)
  188. {
  189. #ifdef CONFIG_FS_MODEM_MOUNT_POINT
  190. return fsMountFsPath(CONFIG_FS_MODEM_MOUNT_POINT, false);
  191. #else
  192. return true;
  193. #endif
  194. }
  195. /**
  196. * Prepare file system for various senario
  197. */
  198. static bool prvFsPrepare(fdlContext_t *d, unsigned kind)
  199. {
  200. switch (kind)
  201. {
  202. case FS_PREPARE_WRITE_PHASECHEK:
  203. case FS_PREPARE_WRITE_FIXEDNV:
  204. case FS_PREPARE_WRITE_PREPACK:
  205. case FS_PREPARE_ERASE_RUNNINGNV:
  206. case FS_PREPARE_ERASE_APPIMG_FILE:
  207. return prvMountFormatFactory(d) && fsMountWithFormatAll();
  208. case FS_PREPARE_READ_PHASECHECK:
  209. case FS_PREPARE_ERASE_PHASECHECK:
  210. return prvMountFactory(d);
  211. case FS_PREPARE_READ_FIXEDNV:
  212. prvMountModem(d); // ignore error
  213. return prvMountFactory(d);
  214. default:
  215. return false;
  216. }
  217. }
  218. /**
  219. * Calculate nvbin size and CRC. It will reuse \p work_mem.
  220. */
  221. static void prvInitNvBinSizeCrc(fdlContext_t *d)
  222. {
  223. d->init_nvbin_size = 0;
  224. if (!prvFsPrepare(d, FS_PREPARE_READ_FIXEDNV))
  225. return;
  226. int nvbin_size = nvmReadFixedBin(NULL, 0);
  227. if (nvbin_size <= 0 || nvbin_size > CONFIG_NVBIN_FIXED_SIZE)
  228. return;
  229. char *nvbin = &d->work_mem[0];
  230. memset(nvbin, 0xff, CONFIG_NVBIN_FIXED_SIZE);
  231. nvmReadFixedBin(nvbin, CONFIG_NVBIN_FIXED_SIZE);
  232. d->init_nvbin_crc = crc32Calc(nvbin, CONFIG_NVBIN_FIXED_SIZE);
  233. d->init_nvbin_size = nvbin_size;
  234. }
  235. /**
  236. * Check whether running should be cleared. It will reuse \p work_mem.
  237. * It is only called after write fixednv.
  238. */
  239. static void prvCheckClearRunning(fdlContext_t *d)
  240. {
  241. #ifdef CONFIG_SOC_8910
  242. if (d->running_cleared)
  243. return;
  244. if (!prvFsPrepare(d, FS_PREPARE_READ_FIXEDNV) ||
  245. !prvFsPrepare(d, FS_PREPARE_ERASE_RUNNINGNV))
  246. return;
  247. int nvbin_size = nvmReadFixedBin(NULL, 0);
  248. if (d->init_nvbin_size > 0 && nvbin_size == d->init_nvbin_size)
  249. {
  250. char *nvbin = &d->work_mem[0];
  251. memset(nvbin, 0xff, CONFIG_NVBIN_FIXED_SIZE);
  252. nvmReadFixedBin(nvbin, CONFIG_NVBIN_FIXED_SIZE);
  253. // do nothing if the nvbin CRC matches
  254. if (crc32Calc(nvbin, CONFIG_NVBIN_FIXED_SIZE) == d->init_nvbin_crc)
  255. return;
  256. }
  257. nvmClearRunning();
  258. d->running_cleared = true;
  259. #endif
  260. }
  261. /**
  262. * BSL_CMD_CONNECT, the timestamp is recorded.
  263. */
  264. static void prvConnect(fdlEngine_t *fdl, fdlContext_t *d)
  265. {
  266. OSI_LOGI(0x10009061, "FDL: connect");
  267. osiElapsedTimerStart(&d->connect_timer);
  268. fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
  269. }
  270. /**
  271. * check whether flash need erase
  272. *
  273. */
  274. static bool prvFlashSkipEraseCheck(bootSpiFlash_t *d, uint32_t offset, size_t size)
  275. {
  276. const uint32_t pattern = 0xffffffff;
  277. const void *fl = bootSpiFlashMapAddress(d, offset);
  278. uint32_t *f_addr = (uint32_t *)fl;
  279. for (int i = 0; i <= size / sizeof(uint32_t); i++)
  280. {
  281. if (f_addr[i] != pattern)
  282. {
  283. OSI_LOGI(0, "CheckFlash: need erase 0x%x/0x%x", f_addr, size);
  284. return false;
  285. }
  286. }
  287. OSI_LOGI(0, "CheckFlash need not erase 0x%x/0x%x", f_addr, size);
  288. return true;
  289. }
  290. /**
  291. * Flash download start. The common information start/total/received has
  292. * already initialized. Return response error code.
  293. */
  294. static int prvFlashStart(fdlContext_t *d)
  295. {
  296. fdlDataDnld_t *dn = &d->dnld;
  297. // Though it doesn't look reasonable, unaligned start address is supported.
  298. // In this case, the write address is not the same as erase address.
  299. dn->write_address = dn->start_address;
  300. dn->erase_address = OSI_ALIGN_DOWN(dn->start_address, FLASH_SECTOR_SIZE);
  301. unsigned faddress = HAL_FLASH_OFFSET(dn->erase_address);
  302. unsigned fend = HAL_FLASH_OFFSET(OSI_ALIGN_UP(dn->start_address + dn->total_size, FLASH_SECTOR_SIZE));
  303. int esize = fend - faddress;
  304. if (prvFlashSkipEraseCheck(dn->flash, faddress, fend - faddress))
  305. {
  306. dn->skip_erase_flash = 1;
  307. }
  308. else
  309. {
  310. dn->skip_erase_flash = 0;
  311. esize = bootSpiFlashEraseNoWait(dn->flash, faddress, fend - faddress);
  312. OSI_LOGD(0, "FDL2 start flash erase no wait 0x%x/0x%x/%d", dn->start_address, fend - faddress, esize);
  313. }
  314. if (esize < 0)
  315. {
  316. dn->flash_stage = FLASH_STAGE_NONE;
  317. OSI_LOGE(0x10009063, "FDL: flash start failed 0x%x/0x%x", dn->start_address, dn->total_size);
  318. return -BSL_REP_DOWN_DEST_ERROR;
  319. }
  320. dn->erase_address += esize;
  321. dn->flash_stage = FLASH_STAGE_ERASE;
  322. dn->data_verify = crc32Init();
  323. return 0;
  324. }
  325. /**
  326. * Flash polling, called in FDL polling, midst and end. Don't access
  327. * \p dnld.received_size, rather the parameter should be used.
  328. */
  329. static void prvFlashPolling(fdlContext_t *d, unsigned received)
  330. {
  331. fdlDataDnld_t *dn = &d->dnld;
  332. if (dn->flash_stage == FLASH_STAGE_NONE ||
  333. dn->flash_stage == FLASH_STAGE_FINISH)
  334. return;
  335. if (dn->flash_stage == FLASH_STAGE_ERASE)
  336. {
  337. if (!bootSpiFlashIsDone(dn->flash))
  338. return;
  339. dn->flash_stage = FLASH_STAGE_WAIT_DATA;
  340. }
  341. else if (dn->flash_stage == FLASH_STAGE_WAIT_DATA)
  342. {
  343. int avail = received - (dn->write_address - dn->start_address);
  344. if (avail < FLASH_PAGE_SIZE || dn->write_address >= dn->erase_address)
  345. return;
  346. unsigned waddress = HAL_FLASH_OFFSET(dn->write_address);
  347. void *wdata = &d->work_mem[dn->write_address % WORKMEM_SIZE];
  348. int wsize = bootSpiFlashWriteNoWait(dn->flash, waddress, wdata, FLASH_PAGE_SIZE);
  349. OSI_LOGV(0x10009064, "FDL2 flash write no wait 0x%x/0x%x", waddress, wsize);
  350. dn->write_address += wsize;
  351. dn->flash_stage = FLASH_STAGE_WRITE;
  352. }
  353. else if (dn->flash_stage == FLASH_STAGE_WRITE)
  354. {
  355. if (!bootSpiFlashIsDone(dn->flash))
  356. return;
  357. if (dn->write_address < dn->erase_address)
  358. {
  359. dn->flash_stage = FLASH_STAGE_WAIT_DATA;
  360. return;
  361. }
  362. unsigned faddress = HAL_FLASH_OFFSET(dn->erase_address);
  363. unsigned fend = HAL_FLASH_OFFSET(OSI_ALIGN_UP(dn->start_address + dn->total_size, FLASH_SECTOR_SIZE));
  364. if (faddress >= fend)
  365. {
  366. dn->flash_stage = FLASH_STAGE_FINISH;
  367. return;
  368. }
  369. int esize = fend - faddress;
  370. if (dn->skip_erase_flash != 1)
  371. {
  372. esize = bootSpiFlashEraseNoWait(dn->flash, faddress, fend - faddress);
  373. OSI_LOGD(0, "FDL2 flash erase no wait 0x%x/0x%x/%d", faddress, fend - faddress, esize);
  374. }
  375. dn->erase_address += esize;
  376. dn->flash_stage = FLASH_STAGE_ERASE;
  377. }
  378. }
  379. /**
  380. * Flash midst
  381. */
  382. static void prvFlashMidst(fdlContext_t *d, const void *data, unsigned size)
  383. {
  384. fdlDataDnld_t *dn = &d->dnld;
  385. dn->data_verify = crc32Update(dn->data_verify, data, size);
  386. // work_mem is reused as ring buffer. The index is address rather than
  387. // size. So, page write can always use linear buffer.
  388. unsigned mem_pos = (dn->start_address + dn->received_size) % WORKMEM_SIZE;
  389. unsigned tail = WORKMEM_SIZE - mem_pos;
  390. if (tail >= size)
  391. {
  392. memcpy(&d->work_mem[mem_pos], data, size);
  393. }
  394. else
  395. {
  396. memcpy(&d->work_mem[mem_pos], data, tail);
  397. memcpy(&d->work_mem[0], (const char *)data + tail, size - tail);
  398. }
  399. // Polling to make sure there are room for the next packet data.
  400. unsigned received = dn->received_size + size;
  401. unsigned received_address = dn->start_address + dn->received_size + size;
  402. while (received_address - dn->write_address > WORKMEM_SIZE - d->max_packet_len)
  403. prvFlashPolling(d, received);
  404. }
  405. /**
  406. * Flash end, write the remaining data and check crc.
  407. */
  408. static int prvFlashEnd(fdlContext_t *d)
  409. {
  410. fdlDataDnld_t *dn = &d->dnld;
  411. // size may be unaligned. So, polling to make sure the remaining data
  412. // less than a page.
  413. unsigned received_address = dn->start_address + dn->received_size;
  414. while (dn->write_address + FLASH_PAGE_SIZE <= received_address)
  415. prvFlashPolling(d, dn->received_size);
  416. // Write the remaining data, if exists.
  417. bootSpiFlashWaitDone(dn->flash);
  418. int remained = received_address - dn->write_address;
  419. if (remained > 0)
  420. {
  421. // It is possible that the remaining are located at unerased sector
  422. unsigned faddress = HAL_FLASH_OFFSET(dn->erase_address);
  423. unsigned fend = HAL_FLASH_OFFSET(OSI_ALIGN_UP(dn->start_address + dn->total_size, FLASH_SECTOR_SIZE));
  424. if (faddress < fend)
  425. {
  426. int esize = fend - faddress;
  427. if (dn->skip_erase_flash != 1)
  428. {
  429. esize = bootSpiFlashErase(dn->flash, faddress, fend - faddress);
  430. OSI_LOGD(0, "FDL2 flash erase 0x%x/0x%x/%d", faddress, fend - faddress, esize);
  431. }
  432. dn->erase_address += esize;
  433. }
  434. unsigned waddress = HAL_FLASH_OFFSET(dn->write_address);
  435. void *wdata = &d->work_mem[dn->write_address % WORKMEM_SIZE];
  436. bootSpiFlashWrite(dn->flash, waddress, wdata, remained);
  437. OSI_LOGV(0x10009066, "FDL2 flash write 0x%x/0x%x", waddress, remained);
  438. }
  439. unsigned fstart = HAL_FLASH_OFFSET(dn->start_address);
  440. const void *fptr = bootSpiFlashMapAddress(dn->flash, fstart);
  441. unsigned fverify = crc32Calc(fptr, dn->total_size);
  442. dn->flash_stage = FLASH_STAGE_NONE;
  443. dn->flash = NULL;
  444. if (fverify != dn->data_verify)
  445. {
  446. OSI_LOGE(0x10009067, "FDL2 flash crc error, start/0x%x size/0x%x crc/0x%x calc/0x%x",
  447. dn->start_address, dn->total_size, dn->data_verify, fverify);
  448. return -BSL_REP_VERIFY_ERROR;
  449. }
  450. return 0;
  451. }
  452. /**
  453. * Write flash after all data received.
  454. */
  455. static int prvFlashWhole(fdlContext_t *d)
  456. {
  457. unsigned start_addr = d->dnld.start_address;
  458. if (d->secure_boot_enable)
  459. {
  460. #ifdef CONFIG_SOC_8910
  461. bool sigcheck = false;
  462. if (start_addr == CONFIG_BOOT_FLASH_ADDRESS)
  463. sigcheck = true;
  464. if (start_addr == CONFIG_APP_FLASH_ADDRESS)
  465. sigcheck = true;
  466. #ifdef CONFIG_FDL_FLASH_SIGCHECK_BEFORE_WRITE
  467. if (start_addr == CONFIG_APPIMG_FLASH_ADDRESS)
  468. sigcheck = true;
  469. #endif
  470. if (sigcheck)
  471. {
  472. // It is magic. Boot check size is fixed, and others has 512 is the cert
  473. // at the end and should be excluded at check.
  474. unsigned check_size = (start_addr == CONFIG_BOOT_FLASH_ADDRESS)
  475. ? BOOT_SIGN_SIZE
  476. : d->dnld.total_size - 512;
  477. OSI_LOGI(0x100090b0, "FDL: image verify 0x%x size %d", (void *)start_addr, check_size);
  478. if (!bootSecureEmbeddedSigCheck(d->flash_mem, check_size))
  479. {
  480. OSI_LOGE(0x100090b1, "FDL: bootloader secure boot verify fail");
  481. return -BSL_REP_VERIFY_ERROR;
  482. }
  483. if (start_addr == CONFIG_BOOT_FLASH_ADDRESS)
  484. {
  485. char *pbuf = d->flash_mem + ENCRYPT_OFF;
  486. bootAntiCloneEncryption(pbuf, ENCRYPT_LEN);
  487. }
  488. }
  489. #endif
  490. #ifdef CONFIG_SOC_8811
  491. bool sigcheck = false;
  492. if (start_addr == CONFIG_BOOT1_FLASH_ADDRESS ||
  493. start_addr == CONFIG_BOOT2_FLASH_ADDRESS)
  494. sigcheck = true;
  495. if (sigcheck)
  496. {
  497. OSI_LOGI(0x100090b0, "FDL: image verify 0x%x size %d", (void *)start_addr, d->dnld.total_size);
  498. const simageHeader_t *header = (const simageHeader_t *)d->flash_mem;
  499. if (!bootSimageCheckSign(header))
  500. {
  501. OSI_LOGE(0x100090b2, "FDL: secure boot verify fail");
  502. return -BSL_REP_OPERATION_FAILED;
  503. }
  504. }
  505. #endif
  506. }
  507. unsigned end_addr = start_addr + d->dnld.total_size;
  508. unsigned erase_offset = OSI_ALIGN_DOWN(HAL_FLASH_OFFSET(start_addr), FLASH_SECTOR_SIZE);
  509. unsigned erase_size = OSI_ALIGN_UP(HAL_FLASH_OFFSET(end_addr) - erase_offset, FLASH_SECTOR_SIZE);
  510. unsigned write_offset = HAL_FLASH_OFFSET(start_addr);
  511. unsigned write_size = d->dnld.total_size;
  512. if (!prvFlashSkipEraseCheck(d->dnld.flash, erase_offset, erase_size))
  513. {
  514. if (!bootSpiFlashErase(d->dnld.flash, erase_offset, erase_size))
  515. return -BSL_REP_VERIFY_ERROR;
  516. }
  517. if (!bootSpiFlashWrite(d->dnld.flash, write_offset, d->flash_mem, write_size))
  518. return -BSL_REP_VERIFY_ERROR;
  519. // For 8910, modem won't be written as a whole. So, there are no
  520. // processing after flash is written.
  521. return 0;
  522. }
  523. /**
  524. * Post check after progressive flash write.
  525. */
  526. static int prvFlashPostCheck(fdlContext_t *d)
  527. {
  528. unsigned start_addr = d->dnld.start_address;
  529. (void)start_addr;
  530. #ifdef CONFIG_SOC_8910
  531. if (start_addr == CONFIG_FS_MODEM_FLASH_ADDRESS)
  532. {
  533. // Modem file system is written by image. So, the block device and
  534. // file system is changed. And it is needed to umount/mount the
  535. // block device and file system. The easiest method is to
  536. // umount/mount all. It will waste some time, and the dynamic memory
  537. // may be considered in memory tight system.
  538. fsUmountAll();
  539. return 0;
  540. }
  541. // The followings are only for secure boot
  542. if (!d->secure_boot_enable)
  543. return 0;
  544. if (start_addr == CONFIG_BOOT_FLASH_ADDRESS)
  545. {
  546. OSI_LOGI(0x100090b4, "FDL: boot image verify 0x%x size %d", (void *)start_addr, d->dnld.total_size);
  547. if (!bootSecureEmbeddedSigCheck((void *)start_addr, BOOT_SIGN_SIZE))
  548. {
  549. OSI_LOGE(0x100090b1, "FDL: bootloader secure boot verify fail");
  550. return -BSL_REP_VERIFY_ERROR;
  551. }
  552. // reuse the working memory
  553. char *pbuf = &d->work_mem[0];
  554. memcpy(pbuf, (void *)(start_addr + ENCRYPT_OFF), FDL_SIZE_4K);
  555. bootAntiCloneEncryption(pbuf, ENCRYPT_LEN);
  556. bootSpiFlash_t *flash = bootSpiFlashOpen(DRV_NAME_SPI_FLASH);
  557. unsigned flash_offset = HAL_FLASH_OFFSET(start_addr);
  558. if (!bootSpiFlashErase(flash, flash_offset + ENCRYPT_OFF, FDL_SIZE_4K))
  559. return -BSL_REP_VERIFY_ERROR;
  560. if (!bootSpiFlashWrite(flash, flash_offset + ENCRYPT_OFF, pbuf, FDL_SIZE_4K))
  561. return -BSL_REP_VERIFY_ERROR;
  562. return 0;
  563. }
  564. if (start_addr == CONFIG_APP_FLASH_ADDRESS)
  565. {
  566. OSI_LOGI(0x100090b5, "FDL: AP image verify 0x%x size %d", (void *)start_addr, d->dnld.total_size);
  567. // It is magic. 512 is the cert at the end and should be excluded at check.
  568. if (!bootSecureEmbeddedSigCheck((void *)start_addr, d->dnld.total_size - 512))
  569. {
  570. OSI_LOGE(0x100090b1, "FDL: bootloader secure boot verify fail");
  571. return -BSL_REP_VERIFY_ERROR;
  572. }
  573. return 0;
  574. }
  575. #ifdef CONFIG_APPIMG_SIGCHECK_ENABLE
  576. if (start_addr == CONFIG_APPIMG_FLASH_ADDRESS)
  577. {
  578. OSI_LOGI(0x100090b6, "FDL: appimg verify 0x%x size %d", (void *)start_addr, d->dnld.total_size);
  579. // It is magic. 512 is the cert at the end and should be excluded at check.
  580. if (!bootSecureEmbeddedSigCheck((void *)start_addr, d->dnld.total_size - 512))
  581. {
  582. OSI_LOGE(0x100090b1, "FDL: bootloader secure boot verify fail");
  583. return -BSL_REP_VERIFY_ERROR;
  584. }
  585. return 0;
  586. }
  587. #endif
  588. #endif
  589. #ifdef CONFIG_SOC_8811
  590. // The followings are only for secure boot
  591. if (!d->secure_boot_enable)
  592. return 0;
  593. if (start_addr == CONFIG_BOOT1_FLASH_ADDRESS ||
  594. start_addr == CONFIG_BOOT2_FLASH_ADDRESS ||
  595. start_addr == CONFIG_APP_FLASH_ADDRESS)
  596. {
  597. OSI_LOGI(0x100090b0, "FDL: image verify 0x%x size %d", (void *)start_addr, d->dnld.total_size);
  598. const simageHeader_t *header = (const simageHeader_t *)start_addr;
  599. if (!bootSimageCheckSign(header))
  600. {
  601. OSI_LOGE(0x100090b2, "FDL: secure boot verify fail");
  602. return -BSL_REP_OPERATION_FAILED;
  603. }
  604. return 0;
  605. }
  606. #endif
  607. return 0;
  608. }
  609. /**
  610. * Write one file from cpio.
  611. */
  612. static void prvPackageFile(cpioFile_t *f)
  613. {
  614. char name[VFS_PATH_MAX + 1] = "/";
  615. bool isdir = f->mode & S_IFDIR;
  616. memcpy(name + 1, f->name, strlen(f->name) + 1);
  617. #ifdef CONFIG_QUEC_PROJECT_FEATURE_BOOT_FAT_RW
  618. QUEC_BOOT_LOG("package file %s (%d/%u)", name, isdir, f->data_size);
  619. #endif
  620. #ifdef CONFIG_QUEC_PROJECT_FEATURE_SPI6_EXT_NOR
  621. extern bool quec_spi6_ext_norflash_get_mount_status(void);
  622. if(!quec_spi6_ext_norflash_get_mount_status())
  623. {
  624. if(strncmp(name, CONFIG_FS_SPI6_EXT_NOR_SFFS_MOUNT_POINT, 4) == 0)
  625. {
  626. QUEC_BOOT_LOG("/ext is not ready to down file");
  627. return;
  628. }
  629. }
  630. #endif
  631. #ifdef CONFIG_QUEC_PROJECT_FEATURE_BOOT_SPI4_EXTNSFFS
  632. if(!quec_spi4_exnsffs_is_mount())
  633. {
  634. if(strncmp(name, CONFIG_FS_SPI4_EXT_NOR_SFFS_MOUNT_POINT, 6) == 0)
  635. {
  636. QUEC_BOOT_LOG("/ext4n is not ready to down file");
  637. return;
  638. }
  639. }
  640. #endif
  641. #ifdef CONFIG_QUEC_PROJECT_FEATURE_BOOT_FAT_RW
  642. if(strncmp(name, CONFIG_FS_SDCARD_MOUNT_POINT, 7) == 0) //"/sdcard0" || "/sdcard1"
  643. {
  644. char *file_name = name + 8; //skip "/sdcard0" || "/sdcard1"
  645. ql_boot_fat_mount_pt_e pt = (name[7] == '0') ? QL_BOOT_FAT_MOUNT_PARTITION_1 : QL_BOOT_FAT_MOUNT_PARTITION_2;
  646. if(ql_boot_fat_open_ex(pt,file_name,QL_BOOT_FAT_OPEN_CREATE) == 0) //Only new and read files are supported
  647. {
  648. if(ql_boot_fat_write_ex (pt,(const void*)f->data, f->data_size) != f->data_size) //Write data to a file
  649. {
  650. QUEC_BOOT_LOG("%s download failed",name);
  651. return;
  652. }
  653. ql_boot_fat_close_ex (pt);
  654. return;
  655. }
  656. QUEC_BOOT_LOG("%s open failed",name);
  657. return;
  658. }
  659. #endif
  660. OSI_LOGXD(OSI_LOGPAR_SII, 0, "package file %s (%d/%u)", name, isdir, f->data_size);
  661. if (isdir)
  662. {
  663. vfs_mkpath(name, 0);
  664. }
  665. else
  666. {
  667. vfs_mkfilepath(name, 0);
  668. vfs_file_write(name, f->data, f->data_size);
  669. }
  670. }
  671. /**
  672. * BSL_CMD_START_DATA
  673. * When file system access is needed, it should be chcked here.
  674. */
  675. static void prvDataStart(fdlEngine_t *fdl, fdlPacket_t *pkt, fdlContext_t *d)
  676. {
  677. int result = 0;
  678. uint32_t *ptr = (uint32_t *)pkt->content;
  679. uint32_t start_addr = OSI_FROM_BE32(*ptr++);
  680. uint32_t file_size = OSI_FROM_BE32(*ptr++);
  681. OSI_LOGI(0x10009068, "FDL: data start, start_addr/0x%x, size/0x%x", start_addr, file_size);
  682. d->dnld.start_address = start_addr;
  683. d->dnld.total_size = file_size;
  684. d->dnld.received_size = 0;
  685. if (start_addr == PHASECHECK_LOGIC_ADDRESS)
  686. {
  687. #ifdef QUEC_PATCH_FACTORY_UPDATE
  688. g_upgrade_by_factory = true;
  689. #endif
  690. if (file_size != sizeof(phaseCheckHead_t))
  691. {
  692. OSI_LOGE(0x100090b7, "FDL: invalid phasecheck data size %d", file_size);
  693. ERR_REP_RETURN(fdl, BSL_REP_DOWN_SIZE_ERROR);
  694. }
  695. if (!prvFsPrepare(d, FS_PREPARE_WRITE_PHASECHEK))
  696. ERR_REP_RETURN(fdl, BSL_REP_INCOMPATIBLE_PARTITION);
  697. }
  698. else if (start_addr == FIXNV_LOGIC_ADDRESS)
  699. {
  700. if (file_size > CONFIG_NVBIN_FIXED_SIZE)
  701. {
  702. OSI_LOGE(0x100090b8, "FDL: invalid fixnv data size %d", file_size);
  703. ERR_REP_RETURN(fdl, BSL_REP_DOWN_SIZE_ERROR);
  704. }
  705. if (!prvFsPrepare(d, FS_PREPARE_WRITE_FIXEDNV))
  706. ERR_REP_RETURN(fdl, BSL_REP_INCOMPATIBLE_PARTITION);
  707. }
  708. else if (start_addr == PRE_PACK_FILE_LOGIC_ADDRESS)
  709. {
  710. if (!prvFsPrepare(d, FS_PREPARE_WRITE_PREPACK))
  711. ERR_REP_RETURN(fdl, BSL_REP_INCOMPATIBLE_PARTITION);
  712. cpioStreamCfg_t cfg = {.file_size_max = PACKAGE_FILE_MAX_SIZE, .file_path_max = VFS_PATH_MAX};
  713. d->cpio = cpioStreamCreate(&cfg);
  714. if (d->cpio == NULL)
  715. ERR_REP_RETURN(fdl, BSL_PHONE_NOT_ENOUGH_MEMORY);
  716. }
  717. else if (IS_FLASH_ADDRESS(start_addr))
  718. {
  719. bootSpiFlash_t *flash = bootSpiFlashOpen(HAL_FLASH_DEVICE_NAME(start_addr));
  720. if (flash == NULL)
  721. ERR_REP_RETURN(fdl, BSL_REP_OPERATION_FAILED);
  722. d->dnld.flash = flash;
  723. d->flash_write_whole = false;
  724. d->dnld.skip_erase_flash = 0;
  725. #ifdef CONFIG_SOC_8910
  726. if (d->secure_boot_enable)
  727. {
  728. if (start_addr == CONFIG_BOOT_FLASH_ADDRESS)
  729. d->flash_write_whole = true;
  730. #ifdef CONFIG_FDL_FLASH_SIGCHECK_BEFORE_WRITE
  731. if (start_addr == CONFIG_APP_FLASH_ADDRESS)
  732. d->flash_write_whole = true;
  733. if (start_addr == CONFIG_APPIMG_FLASH_ADDRESS)
  734. d->flash_write_whole = true;
  735. #endif
  736. }
  737. #endif
  738. #ifdef CONFIG_SOC_8811
  739. if (d->secure_boot_enable)
  740. {
  741. if (start_addr == CONFIG_BOOT1_FLASH_ADDRESS ||
  742. start_addr == CONFIG_BOOT2_FLASH_ADDRESS)
  743. d->flash_write_whole = true;
  744. }
  745. #endif
  746. if (d->flash_write_whole)
  747. {
  748. d->flash_mem = malloc(d->dnld.total_size);
  749. if (d->flash_mem == NULL)
  750. ERR_REP_RETURN(fdl, BSL_PHONE_NOT_ENOUGH_MEMORY);
  751. }
  752. else
  753. {
  754. if ((result = prvFlashStart(d)) < 0)
  755. ERR_REP_RETURN(fdl, -result);
  756. }
  757. }
  758. else
  759. {
  760. OSI_LOGE(0x100090b9, "FDL: invalid data start address 0x%x", start_addr);
  761. fdlEngineSendRespNoData(fdl, BSL_REP_DOWN_DEST_ERROR);
  762. return;
  763. }
  764. d->dnld.stage = SYS_STAGE_START;
  765. fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
  766. }
  767. /**
  768. * BSL_CMD_MIDST_DATA
  769. */
  770. static void prvDataMidst(fdlEngine_t *fdl, fdlPacket_t *pkt, fdlContext_t *d)
  771. {
  772. uint16_t data_len = pkt->size;
  773. uint32_t start_addr = d->dnld.start_address;
  774. OSI_LOGD(0x10009069, "FDL: data midst, start_addr/0x%x, size/0x%x, received/0x%x, len/0x%x, stage/0x%x",
  775. d->dnld.start_address, d->dnld.total_size, d->dnld.received_size,
  776. data_len, d->dnld.stage);
  777. if ((d->dnld.stage != SYS_STAGE_START) && (d->dnld.stage != SYS_STAGE_GATHER))
  778. {
  779. d->dnld.flash_stage = FLASH_STAGE_NONE;
  780. d->dnld.flash = NULL;
  781. ERR_REP_RETURN(fdl, BSL_REP_DOWN_NOT_START);
  782. }
  783. if (d->dnld.received_size + data_len > d->dnld.total_size)
  784. {
  785. d->dnld.flash_stage = FLASH_STAGE_NONE;
  786. d->dnld.flash = NULL;
  787. ERR_REP_RETURN(fdl, BSL_REP_DOWN_SIZE_ERROR);
  788. }
  789. if (start_addr == PRE_PACK_FILE_LOGIC_ADDRESS)
  790. {
  791. #ifdef __QUEC_OEM_VER_TY__
  792. static bool isClear = false;
  793. if (isClear == false)
  794. {
  795. vfs_rmchildren(CONFIG_FS_SYS_MOUNT_POINT);
  796. isClear = true;
  797. }
  798. #endif
  799. cpioStreamPushData(d->cpio, pkt->content, data_len);
  800. cpioFile_t *f;
  801. while ((f = cpioStreamPopFile(d->cpio)))
  802. {
  803. #if defined(CONFIG_SOC_8910) && defined(CONFIG_APPIMG_LOAD_FILE) && \
  804. defined(CONFIG_APPIMG_LOAD_FILE_NAME) && defined(CONFIG_APPIMG_SIGCHECK_ENABLE)
  805. if (d->secure_boot_enable && strcmp(f->name, &CONFIG_APPIMG_LOAD_FILE_NAME[1]) == 0)
  806. {
  807. OSI_LOGI(0x1000906a, "FDL: appimg file verify size %d", f->data_size);
  808. // It is magic. The length of bootSecureEmbeddedSigCheck is raw data plus sig.
  809. // However, there are 512 bytes cert in appimg.
  810. if (!bootSecureEmbeddedSigCheck(f->data, f->data_size - 512))
  811. {
  812. OSI_LOGE(0x100090b1, "FDL: bootloader secure boot verify fail");
  813. ERR_REP_RETURN(fdl, BSL_REP_VERIFY_ERROR);
  814. }
  815. }
  816. #endif
  817. prvPackageFile(f);
  818. cpioStreamDestroyFile(d->cpio, f);
  819. }
  820. }
  821. else if (IS_FLASH_ADDRESS(start_addr))
  822. {
  823. if (d->flash_write_whole)
  824. memcpy(&d->flash_mem[0] + d->dnld.received_size, pkt->content, data_len);
  825. else
  826. prvFlashMidst(d, pkt->content, data_len);
  827. }
  828. else if (d->dnld.received_size + data_len > WORKMEM_SIZE)
  829. {
  830. ERR_REP_RETURN(fdl, BSL_REP_DOWN_SIZE_ERROR);
  831. }
  832. else
  833. {
  834. memcpy(&d->work_mem[0] + d->dnld.received_size, pkt->content, data_len);
  835. }
  836. d->dnld.received_size += data_len;
  837. d->dnld.stage = SYS_STAGE_GATHER;
  838. fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
  839. }
  840. /**
  841. * BSL_CMD_END_DATA
  842. */
  843. static void prvDataEnd(fdlEngine_t *fdl, fdlContext_t *d)
  844. {
  845. int result = 0;
  846. uint32_t start_addr = d->dnld.start_address;
  847. OSI_LOGI(0x1000906b, "FDL: data end, start_addr/0x%x, size/0x%x, received/0x%x, stage/0x%x",
  848. d->dnld.start_address, d->dnld.total_size, d->dnld.received_size,
  849. d->dnld.stage);
  850. if ((d->dnld.stage != SYS_STAGE_START) && (d->dnld.stage != SYS_STAGE_GATHER))
  851. {
  852. d->dnld.flash_stage = FLASH_STAGE_NONE;
  853. d->dnld.flash = NULL;
  854. ERR_REP_RETURN(fdl, BSL_REP_DOWN_NOT_START);
  855. }
  856. if (d->dnld.received_size != d->dnld.total_size)
  857. {
  858. d->dnld.flash_stage = FLASH_STAGE_NONE;
  859. d->dnld.flash = NULL;
  860. ERR_REP_RETURN(fdl, BSL_REP_DOWN_SIZE_ERROR);
  861. }
  862. if (start_addr == PHASECHECK_LOGIC_ADDRESS)
  863. {
  864. phaseCheckHead_t *phase_check = (phaseCheckHead_t *)&d->work_mem[0];
  865. if (!nvmWritePhaseCheck(phase_check))
  866. {
  867. OSI_LOGE(0x100090ba, "FDL: write phase check failed");
  868. ERR_REP_RETURN(fdl, BSL_REP_OPERATION_FAILED);
  869. }
  870. }
  871. else if (start_addr == FIXNV_LOGIC_ADDRESS)
  872. {
  873. char *nvbin = &d->work_mem[0];
  874. #ifdef QUEC_PATCH_FACTORY_UPDATE
  875. if (nvmWriteFixedBin_v2(nvbin, d->dnld.received_size, g_upgrade_by_factory) < 0)
  876. #else
  877. if (nvmWriteFixedBin(nvbin, d->dnld.received_size) < 0)
  878. #endif
  879. {
  880. OSI_LOGE(0x100090bb, "FDL: write nv bin failed");
  881. ERR_REP_RETURN(fdl, BSL_REP_OPERATION_FAILED);
  882. }
  883. if (d->phasecheck_backed)
  884. {
  885. d->phasecheck_backed = false;
  886. if (!nvmWritePhaseCheck(&d->phasecheck_back))
  887. {
  888. OSI_LOGE(0x100090bc, "FDL: write phasecheck fail after erase all");
  889. ERR_REP_RETURN(fdl, BSL_REP_OPERATION_FAILED);
  890. }
  891. }
  892. d->fixednv_backed = false;
  893. prvCheckClearRunning(d);
  894. }
  895. else if (start_addr == PRE_PACK_FILE_LOGIC_ADDRESS)
  896. {
  897. cpioStreamDestroy(d->cpio);
  898. d->cpio = NULL;
  899. }
  900. else if (IS_FLASH_ADDRESS(start_addr))
  901. {
  902. if (d->flash_write_whole)
  903. {
  904. d->flash_write_whole = false;
  905. result = prvFlashWhole(d);
  906. free(d->flash_mem);
  907. d->flash_mem = NULL;
  908. if (result < 0)
  909. ERR_REP_RETURN(fdl, -result);
  910. }
  911. else
  912. {
  913. if ((result = prvFlashEnd(d)) < 0)
  914. ERR_REP_RETURN(fdl, -result);
  915. if ((result = prvFlashPostCheck(d)) < 0)
  916. ERR_REP_RETURN(fdl, -result);
  917. }
  918. }
  919. d->dnld.stage = SYS_STAGE_END;
  920. fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
  921. }
  922. /**
  923. * BSL_CMD_NORMAL_RESET
  924. */
  925. static void prvResetNormal(fdlEngine_t *fdl, fdlContext_t *d)
  926. {
  927. OSI_LOGI(0x1000906c, "FDL: reset to normal");
  928. fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
  929. osiDelayUS(2000);
  930. bootReset(BOOT_RESET_NORMAL);
  931. }
  932. /**
  933. * Polling for delayed poweroff
  934. */
  935. static void prvPowerOffPolling(fdlContext_t *d)
  936. {
  937. if (!d->delay_poweroff)
  938. return;
  939. if (BOOT_DNLD_FROM_UART(d->device_type))
  940. {
  941. unsigned ms = osiElapsedTime(&d->connect_timer);
  942. if (ms > DELAY_POWEROFF_TIMEOUT)
  943. {
  944. OSI_LOGI(0x1000906d, "FDL: poweroff timeout", ms);
  945. bootPowerOff();
  946. // ideally, we shouldn't come here
  947. OSI_LOGE(0x1000906e, "FDL: poweroff failed");
  948. d->delay_poweroff = false;
  949. }
  950. }
  951. if (BOOT_DNLD_FROM_USERIAL(d->device_type))
  952. {
  953. if (!d->channel->connected(d->channel))
  954. {
  955. OSI_LOGI(0x1000906f, "FDL: device not connected, poweroff");
  956. bootPowerOff();
  957. // ideally, we shouldn't come here
  958. OSI_LOGE(0x1000906e, "FDL: poweroff failed");
  959. d->delay_poweroff = false;
  960. }
  961. }
  962. }
  963. /**
  964. * BSL_CMD_POWER_OFF
  965. */
  966. static void prvPowerOff(fdlEngine_t *fdl, fdlContext_t *d)
  967. {
  968. OSI_LOGI(0x10009070, "FDL: poweroff");
  969. d->delay_poweroff = true;
  970. osiElapsedTimerStart(&d->connect_timer);
  971. fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
  972. }
  973. /**
  974. * BSL_CMD_READ_FLASH
  975. */
  976. static void prvReadFlash(fdlEngine_t *fdl, fdlPacket_t *pkt, fdlContext_t *d)
  977. {
  978. uint32_t *ptr = (uint32_t *)pkt->content;
  979. uint32_t addr = OSI_FROM_BE32(*ptr++);
  980. uint32_t size = OSI_FROM_BE32(*ptr++);
  981. uint32_t offset = OSI_FROM_BE32(*ptr++); // not all address has this parameter
  982. if (offset == 0)
  983. OSI_LOGI(0x10009071, "FDL: read flash, addr/0x%x, size/0x%x, offset/0x%x", addr, size, offset);
  984. else
  985. OSI_LOGD(0x10009071, "FDL: read flash, addr/0x%x, size/0x%x, offset/0x%x", addr, size, offset);
  986. if (addr == PHASECHECK_LOGIC_ADDRESS)
  987. {
  988. if (!prvFsPrepare(d, FS_PREPARE_READ_PHASECHECK))
  989. ERR_REP_RETURN(fdl, BSL_REP_INCOMPATIBLE_PARTITION);
  990. // reuse the working memory
  991. phaseCheckHead_t *phase_check = (phaseCheckHead_t *)&d->work_mem[0];
  992. memset(phase_check, 0, sizeof(phaseCheckHead_t));
  993. if (!nvmReadPhasecheck(phase_check))
  994. {
  995. OSI_LOGE(0x100090bd, "FDL: read phasecheck failed");
  996. ERR_REP_RETURN(fdl, BSL_REP_OPERATION_FAILED);
  997. }
  998. fdlEngineSendRespData(fdl, BSL_REP_READ_FLASH, phase_check, sizeof(phaseCheckHead_t));
  999. }
  1000. else if (addr == FIXNV_LOGIC_ADDRESS)
  1001. {
  1002. // Assuming the read will be started with offset 0, and continuous
  1003. char *nvbin = &d->work_mem[0];
  1004. if (offset == 0)
  1005. {
  1006. if (d->fixednv_backed)
  1007. {
  1008. d->fixednv_backed = false;
  1009. memcpy(nvbin, d->fixednv_back, CONFIG_NVBIN_FIXED_SIZE);
  1010. }
  1011. else
  1012. {
  1013. if (!prvFsPrepare(d, FS_PREPARE_READ_FIXEDNV))
  1014. ERR_REP_RETURN(fdl, BSL_REP_INCOMPATIBLE_PARTITION);
  1015. memset(nvbin, 0xff, CONFIG_NVBIN_FIXED_SIZE);
  1016. if (nvmReadFixedBin(nvbin, CONFIG_NVBIN_FIXED_SIZE) < 0)
  1017. ERR_REP_RETURN(fdl, BSL_REP_OPERATION_FAILED);
  1018. }
  1019. }
  1020. if (offset >= CONFIG_NVBIN_FIXED_SIZE)
  1021. ERR_REP_RETURN(fdl, BSL_REP_INVALID_CMD);
  1022. unsigned send_size = OSI_MIN(unsigned, CONFIG_NVBIN_FIXED_SIZE - offset, size);
  1023. fdlEngineSendRespData(fdl, BSL_REP_READ_FLASH, nvbin + offset, send_size);
  1024. }
  1025. else if (IS_FLASH_ADDRESS(addr))
  1026. {
  1027. bootSpiFlash_t *flash = bootSpiFlashOpen(HAL_FLASH_DEVICE_NAME(addr));
  1028. if (flash == NULL)
  1029. ERR_REP_RETURN(fdl, BSL_REP_OPERATION_FAILED);
  1030. // valid flash offset not includes the end address
  1031. if (!bootSpiFlashMapAddressValid(flash, (void *)(addr + size - 1)))
  1032. ERR_REP_RETURN(fdl, BSL_REP_INVALID_CMD);
  1033. uint32_t flash_offset = HAL_FLASH_OFFSET(addr);
  1034. const void *fdata = bootSpiFlashMapAddress(flash, flash_offset);
  1035. fdlEngineSendRespData(fdl, BSL_REP_READ_FLASH, fdata, size);
  1036. }
  1037. else
  1038. {
  1039. fdlEngineSendRespNoData(fdl, BSL_REP_INVALID_CMD);
  1040. return;
  1041. }
  1042. }
  1043. /**
  1044. * BSL_CMD_ERASE_FLASH
  1045. */
  1046. static void prvEraseFlash(fdlEngine_t *fdl, fdlPacket_t *pkt, fdlContext_t *d)
  1047. {
  1048. uint32_t *ptr = (uint32_t *)pkt->content;
  1049. uint32_t addr = OSI_FROM_BE32(*ptr++);
  1050. uint32_t size = OSI_FROM_BE32(*ptr++);
  1051. OSI_LOGI(0x10009072, "FDL: erase flash, addr/0x%x, size/0x%x", addr, size);
  1052. if (addr == ERASE_RUNNING_NV_LOGIC_ADDRESS)
  1053. {
  1054. if (!prvFsPrepare(d, FS_PREPARE_ERASE_RUNNINGNV))
  1055. ERR_REP_RETURN(fdl, BSL_REP_INCOMPATIBLE_PARTITION);
  1056. nvmClearRunning(); // ignore error
  1057. d->running_cleared = true;
  1058. }
  1059. else if (addr == PHASECHECK_LOGIC_ADDRESS)
  1060. {
  1061. if (!prvFsPrepare(d, FS_PREPARE_ERASE_PHASECHECK))
  1062. ERR_REP_RETURN(fdl, BSL_REP_INCOMPATIBLE_PARTITION);
  1063. nvmClearPhaseCheck(); // ignore error
  1064. }
  1065. else if (addr == DEL_APPIMG_LOGIC_ADDRESS)
  1066. {
  1067. #if defined(CONFIG_APPIMG_LOAD_FLASH) && defined(CONFIG_APPIMG_LOAD_FILE_NAME)
  1068. if (!prvFsPrepare(d, FS_PREPARE_ERASE_APPIMG_FILE))
  1069. ERR_REP_RETURN(fdl, BSL_REP_INCOMPATIBLE_PARTITION);
  1070. vfs_unlink(CONFIG_APPIMG_LOAD_FILE_NAME); // ignore error
  1071. #endif
  1072. }
  1073. else if (addr == FMT_FLASH_LOGIC_ADDRESS)
  1074. {
  1075. // "size" is the flash block device name
  1076. if (!fsMountFormatFlash(size))
  1077. ERR_REP_RETURN(fdl, BSL_REP_OPERATION_FAILED);
  1078. }
  1079. else if (FLASH_ERASE_ALL == addr && FLASH_ERASE_ALL_SIZE == size)
  1080. {
  1081. if (prvFsPrepare(d, FS_PREPARE_READ_PHASECHECK) &&
  1082. nvmReadPhasecheck(&d->phasecheck_back))
  1083. d->phasecheck_backed = true;
  1084. if (prvFsPrepare(d, FS_PREPARE_READ_FIXEDNV))
  1085. {
  1086. int nvsize = nvmReadFixedBin(d->fixednv_back, CONFIG_NVBIN_FIXED_SIZE);
  1087. if (nvsize > 0 && nvsize <= CONFIG_NVBIN_FIXED_SIZE)
  1088. d->fixednv_backed = true;
  1089. }
  1090. fsUmountAll();
  1091. bootSpiFlash_t *flash = bootSpiFlashOpen(DRV_NAME_SPI_FLASH);
  1092. if (flash == NULL)
  1093. ERR_REP_RETURN(fdl, BSL_REP_OPERATION_FAILED);
  1094. uint32_t capcaity = bootSpiFlashCapacity(flash);
  1095. if (!prvFlashSkipEraseCheck(flash, 0, capcaity))
  1096. {
  1097. bootSpiFlashChipErase(flash);
  1098. }
  1099. #ifdef CONFIG_QUEC_PROJECT_FEATURE_SPI6_EXT_NOR
  1100. bootSpiFlash_t *flash_ext = bootSpiFlashOpen(DRV_NAME_SPI_FLASH_EXT);
  1101. if (flash_ext != NULL)
  1102. {
  1103. bootSpiFlashChipErase(flash_ext);
  1104. }
  1105. #else
  1106. #ifdef CONFIG_BOARD_WITH_EXT_FLASH
  1107. bootSpiFlash_t *flash_ext = bootSpiFlashOpen(DRV_NAME_SPI_FLASH_EXT);
  1108. if (flash_ext == NULL)
  1109. ERR_REP_RETURN(fdl, BSL_REP_OPERATION_FAILED);
  1110. uint32_t capcaity_ext = bootSpiFlashCapacity(flash_ext);
  1111. if (!prvFlashSkipEraseCheck(flash_ext, 0, capcaity_ext))
  1112. {
  1113. bootSpiFlashChipErase(flash_ext);
  1114. }
  1115. #endif
  1116. #endif
  1117. }
  1118. else if (IS_FLASH_ADDRESS(addr))
  1119. {
  1120. bootSpiFlash_t *flash = bootSpiFlashOpen(HAL_FLASH_DEVICE_NAME(addr));
  1121. #ifdef CONFIG_QUEC_PROJECT_FEATURE_SPI6_EXT_NOR
  1122. if (flash != NULL)
  1123. {
  1124. uint32_t flash_offset = HAL_FLASH_OFFSET(addr);
  1125. if (!bootSpiFlashErase(flash, flash_offset, size))
  1126. {
  1127. ERR_REP_RETURN(fdl, BSL_REP_INVALID_CMD);
  1128. }
  1129. }
  1130. #else
  1131. uint32_t flash_offset = HAL_FLASH_OFFSET(addr);
  1132. if (!prvFlashSkipEraseCheck(flash, flash_offset, size))
  1133. {
  1134. if (!bootSpiFlashErase(flash, flash_offset, size))
  1135. ERR_REP_RETURN(fdl, BSL_REP_INVALID_CMD);
  1136. }
  1137. #endif
  1138. }
  1139. else
  1140. {
  1141. fdlEngineSendRespNoData(fdl, BSL_REP_INVALID_CMD);
  1142. return;
  1143. }
  1144. fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
  1145. }
  1146. /**
  1147. * BSL_CMD_CHANGE_BAUD
  1148. */
  1149. static void prvSetBaud(fdlEngine_t *fdl, fdlPacket_t *pkt, fdlContext_t *d)
  1150. {
  1151. uint32_t *ptr = (uint32_t *)pkt->content;
  1152. uint32_t baud = OSI_FROM_BE32(*ptr++);
  1153. OSI_LOGD(0x10009073, "FDL: change baud %d", baud);
  1154. // This is special, ACK must be sent in old baud rate.
  1155. fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
  1156. fdlEngineSetBaud(fdl, baud);
  1157. }
  1158. /**
  1159. * Process packet, called by engine.
  1160. */
  1161. static void prvProcessPkt(fdlEngine_t *fdl, fdlPacket_t *pkt, void *param)
  1162. {
  1163. if (fdl == NULL || pkt == NULL)
  1164. osiPanic();
  1165. OSI_LOGV(0x10009074, "FDL: pkt type/0x%x, size/0x%x", pkt->type, pkt->size);
  1166. fdlContext_t *d = (fdlContext_t *)param;
  1167. switch (pkt->type)
  1168. {
  1169. case BSL_CMD_CONNECT:
  1170. prvConnect(fdl, d);
  1171. break;
  1172. case BSL_CMD_START_DATA:
  1173. prvDataStart(fdl, pkt, d);
  1174. break;
  1175. case BSL_CMD_MIDST_DATA:
  1176. prvDataMidst(fdl, pkt, d);
  1177. break;
  1178. case BSL_CMD_END_DATA:
  1179. prvDataEnd(fdl, d);
  1180. break;
  1181. case BSL_CMD_NORMAL_RESET:
  1182. prvResetNormal(fdl, d);
  1183. break;
  1184. case BSL_CMD_READ_FLASH:
  1185. prvReadFlash(fdl, pkt, d);
  1186. break;
  1187. case BSL_CMD_REPARTITION:
  1188. OSI_LOGI(0x100090be, "FDL: repartition");
  1189. fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
  1190. break;
  1191. case BSL_CMD_ERASE_FLASH:
  1192. prvEraseFlash(fdl, pkt, d);
  1193. break;
  1194. case BSL_CMD_POWER_OFF:
  1195. prvPowerOff(fdl, d);
  1196. break;
  1197. case BSL_CMD_CHANGE_BAUD:
  1198. prvSetBaud(fdl, pkt, d);
  1199. break;
  1200. case BSL_CMD_ENABLE_DEBUG_MODE:
  1201. fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
  1202. break;
  1203. default:
  1204. OSI_LOGE(0x100090bf, "FDL: cmd not support yet 0x%x", pkt->type);
  1205. fdlEngineSendRespNoData(fdl, BSL_REP_INVALID_CMD);
  1206. break;
  1207. }
  1208. }
  1209. /**
  1210. * Polling. Called by engine
  1211. */
  1212. static void prvPolling(fdlEngine_t *fdl, void *param)
  1213. {
  1214. fdlContext_t *d = (fdlContext_t *)param;
  1215. prvFlashPolling(d, d->dnld.received_size);
  1216. prvPowerOffPolling(d);
  1217. }
  1218. /**
  1219. * Start download
  1220. */
  1221. bool fdlDnldStart(fdlEngine_t *fdl, unsigned devtype)
  1222. {
  1223. fdlContext_t *d = calloc(1, sizeof(fdlContext_t));
  1224. if (d == NULL)
  1225. return false;
  1226. halPmuExtFlashPowerOn();
  1227. d->device_type = devtype;
  1228. d->channel = fdlEngineGetChannel(fdl);
  1229. d->max_packet_len = fdlEngineGetMaxPacketLen(fdl);
  1230. d->secure_boot_enable = bootSecureBootEnable();
  1231. fsMountSetScenario(FS_SCENRARIO_FDL);
  1232. prvInitNvBinSizeCrc(d);
  1233. #if 0
  1234. /*
  1235. If you want to down file to ext spi6 nor flash, you can open this code to mount it,
  1236. then the file will be download to ext spi6 nor flash
  1237. */
  1238. #ifdef CONFIG_QUEC_PROJECT_FEATURE_SPI6_EXT_NOR
  1239. extern void ql_boot_set_skip_spi6_ext_norflash_init(bool onff);
  1240. OSI_LOGE(0, "demo: boot not skip ext spi6 norflash");
  1241. ql_boot_set_skip_spi6_ext_norflash_init(false);
  1242. #endif
  1243. #endif
  1244. #if 0
  1245. /*
  1246. If you want to down file to extn spi4 nor flash, you can open this code to mount it,
  1247. then the file will be download to extn spi4 nor flash
  1248. */
  1249. #ifdef CONFIG_QUEC_PROJECT_FEATURE_BOOT_SPI4_EXTNSFFS
  1250. ql_boot_spi4_nor_flash_init(); //Initial spi4 nor Flash
  1251. if(fsMountGeneralSpiFlash(false)) //Mount the SFFS file system
  1252. {
  1253. //Whether to format if the mount fails
  1254. //fsMountGeneralSpiFlash(true); //Format the SFFS file system
  1255. }
  1256. #endif
  1257. #endif
  1258. #if 0
  1259. /*
  1260. If you want to down file to sdmmc, you can open this code to init sdmmc & mount it,
  1261. then the file will be download to "/sdcard0"
  1262. */
  1263. #ifdef CONFIG_QUEC_PROJECT_FEATURE_BOOT_FAT_RW
  1264. #if (defined CONFIG_QUEC_PROJECT_FEATURE_BOOT_SDMMC)
  1265. //挂载预置文件的路径选择,可以同时挂载两个分区
  1266. ql_boot_sdmmc_cfg.power_mv = POWER_LEVEL_3200MV; //default sdcard voltage is 3.2 V
  1267. ql_boot_sdmmc_cfg.sdmmc_clk = SDMMC_CLK_FREQ_SDHC; //400000 <= freq <= 50000000,
  1268. //default sdcard clk is 50MHz(SDHC) or 25MHz(NOT SDHC).
  1269. quec_boot_sdmmc_init_ex(QL_BOOT_FAT_MOUNT_PARTITION_1); // "/sdcard0" 挂载分区1,如果没有分区,
  1270. 默认分区1
  1271. //quec_boot_sdmmc_init_ex(QL_BOOT_FAT_MOUNT_PARTITION_2); // "/sdcard1" 挂载分区2
  1272. #elif (defined CONFIG_QUEC_PROJECT_FEATURE_BOOT_EMMC)
  1273. //挂载预置文件的路径选择,可以同时挂载两个分区
  1274. ql_boot_sdmmc_cfg.power_mv = POWER_LEVEL_1800MV; //default emmc voltage is 1.8 V
  1275. ql_boot_sdmmc_cfg.sdmmc_clk = SDMMC_CLK_FREQ_SD; //default emmc clk is 25MHz
  1276. quec_boot_emmc_init_ex(QL_BOOT_FAT_MOUNT_PARTITION_1); // "/sdcard0" 挂载分区1,如果没有分区,默认分区1
  1277. //quec_boot_emmc_init_ex(QL_BOOT_FAT_MOUNT_PARTITION_2); // "/sdcard1" 挂载分区2
  1278. #endif
  1279. #endif
  1280. #endif
  1281. #if 0
  1282. /*
  1283. If you want to format user file system when download firmware, you can open this code to do it,
  1284. it will delete all files at the flash partition which for file system.
  1285. Be careful,do not open this part of the code,if you have already opened QUEC_PROJECT_FEATURE_PROG_FW_FMTEXT in your target.config.
  1286. */
  1287. fsMountFormat(CONFIG_FS_SYS_MOUNT_POINT);
  1288. #endif
  1289. //20221012 modified by ryan.yi。将TTS改成QUECTEL宏控。无论TTS是否打开,烧录时,默认删除预置文件
  1290. #ifdef CONFIG_QUEC_PROJECT_FEATURE
  1291. vfs_unlink(TTS_PREPACK_FILE_PATH);
  1292. //20210926 之前的版本英文TTS使用此文件名,后续TTS资源文件名将统一使用TTS_PREPACK_FILE_PATH
  1293. vfs_unlink(TTS_EN_PREPACK_FILE_PATH);
  1294. //ryan.yi added 20220217 tts资源文件拆分成多个资源文件
  1295. vfs_unlink(QL_TTS_RESOURCE_APPEND_BIN);
  1296. vfs_unlink(QL_TTS_RESOURCE_END_BIN);
  1297. int i =0;
  1298. char tts_append_name[256] = {0};
  1299. for (i=0; i<QL_TTS_RESOURCE_PACKET_MAX; i++)
  1300. {
  1301. //只是用来先确定有没有预置文件要合并
  1302. memset(tts_append_name, 0x00, sizeof(tts_append_name));
  1303. snprintf(tts_append_name, sizeof(tts_append_name), "/qsfs/quectel_pcm_resource_%02d.bin", i);
  1304. vfs_unlink(tts_append_name);
  1305. }
  1306. #endif
  1307. #ifdef CONFIG_QUEC_PROJECT_FEATURE
  1308. //When downloading, the FOTA stage file is deleted by default, prevent repeated restart failure caused by downloading the file during FOTA upgrade
  1309. vfs_unlink(FUPDATE_STAGE_FILE_NAME);
  1310. #endif
  1311. fdlEngineProcess(fdl, prvProcessPkt, prvPolling, d);
  1312. // In normal case, we won't come here.
  1313. free(d);
  1314. return false;
  1315. }