fdl.c 43 KB

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