12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421 |
- /* Copyright (C) 2019 RDA Technologies Limited and/or its affiliates("RDA").
- * All rights reserved.
- *
- * This software is supplied "AS IS" without any warranties.
- * RDA assumes no responsibility or liability for the use of the software,
- * conveys no license or title under any patent, copyright, or mask work
- * right to the product. RDA reserves the right to make changes in the
- * software without notification. RDA also make no representation or
- * warranty that such application will be suitable for the specified use
- * without further testing or modification.
- */
- #define OSI_LOCAL_LOG_TAG OSI_MAKE_LOG_TAG('F', 'D', 'L', '1')
- // #define OSI_LOCAL_LOG_LEVEL OSI_LOG_LEVEL_DEBUG
- #include "boot_fdl.h"
- #include "boot_entry.h"
- #include "boot_platform.h"
- #include "boot_mem.h"
- #include "boot_mmu.h"
- #include "boot_spi_flash.h"
- #include "hal_chip.h"
- #include "boot_secure.h"
- #include "boot_bsl_cmd.h"
- #include "hal_config.h"
- #include "cmsis_core.h"
- #include "osi_log.h"
- #include "osi_api.h"
- #include "drv_names.h"
- #include "diag_config.h"
- #include "hwregs.h"
- #include "cpio_parser.h"
- #include "nvm.h"
- #include "vfs.h"
- #include "fs_mount.h"
- #include "calclib/crc32.h"
- #include "hal_adi_bus.h"
- #include "8850/hal_rom_api.h"
- #include <sys/reent.h>
- #include <string.h>
- #include <stdlib.h>
- #ifdef CONFIG_QUEC_PROJECT_FEATURE
- #include "quec_boot_log.h"
- #include "quec_cust_patch.h"
- #include "quec_proj_config.h"
- #include "quec_boot_file_cfg.h"
- #include "quec_internal_cfg.h"
- #include "fupdate_config.h"
- #endif
- #ifdef CONFIG_QUEC_PROJECT_FEATURE_BOOT_SPI4_EXTNSFFS
- #include "fs_mount_spiflash.h"
- #include "ql_boot_spi4_exnsffs_cfg.h"
- #endif
- #ifdef CONFIG_QUEC_PROJECT_FEATURE_BOOT_FAT_RW
- #include "quec_boot_pff.h"
- #ifdef QUEC_PROJECT_FEATURE_BOOT_SD_EMMC
- #include "quec_boot_sdmmc.h"
- #include "drv_sdmmc_imp.h"
- extern ql_boot_sdmmc_cfg_t ql_boot_sdmmc_cfg; //sdmmc配置
- #endif
- #endif
- // Work memory size in context
- #define WORKMEM_SIZE (CONFIG_NVBIN_FIXED_SIZE < 0x10000 ? 0x10000 : CONFIG_NVBIN_FIXED_SIZE)
- #ifdef CONFIG_QUEC_PROJECT_FEATURE
- #define PACKAGE_FILE_MAX_SIZE 0x190000
- #else
- #define PACKAGE_FILE_MAX_SIZE 0x10000
- #endif
- #ifdef CONFIG_QUEC_PROJECT_FEATURE
- #define TTS_PREPACK_FILE_PATH "/qsfs/quectel_pcm_resource.bin"
- #define TTS_EN_PREPACK_FILE_PATH "/qsfs/quectel_pcm_english.bin"
- #define GNSS_BOOT_FILE_PATH "/user/boot"
- #define GNSS_FIRM_FILE_PATH "/user/firm"
- #define QL_TTS_RESOURCE_APPEND_BIN "/qsfs/quectel_pcm_resource_append.bin"
- #define QL_TTS_RESOURCE_END_BIN "/qsfs/quectel_pcm_resource_ff.bin"
- #define QL_TTS_RESOURCE_PACKET_MAX 10
- #endif
- #define FIXEDNV_ID_COUNT_MAX (64)
- // Logic addresses, which should match the value used in pac file
- #define ERASE_RUNNING_NV_LOGIC_ADDRESS 0xFE000001
- #define PHASECHECK_LOGIC_ADDRESS 0xFE000002
- #define FIXNV_LOGIC_ADDRESS 0xFE000003
- #define PRE_PACK_FILE_LOGIC_ADDRESS 0xFE000004
- #define DEL_APPIMG_LOGIC_ADDRESS 0xFE000005
- #define FMT_FLASH_LOGIC_ADDRESS 0xFE000006
- #define FLASH_ERASE_ALL 0x00000000
- #define FLASH_ERASE_ALL_SIZE 0xFFFFFFFF
- #define FLASH_PAGE_SIZE (256)
- #define FLASH_SECTOR_SIZE (0x1000)
- #define FDL_SIZE_4K (0x1000)
- #define DELAY_POWEROFF_TIMEOUT (2000)
- #define ERR_REP_RETURN(fdl, err) OSI_DO_WHILE0(fdlEngineSendRespNoData(fdl, err); return;)
- #if (defined CONFIG_BOARD_WITH_EXT_FLASH) || (defined CONFIG_QUEC_PROJECT_FEATURE_SPI6_EXT_NOR) || (defined CONFIG_QUEC_PROJECT_FEATURE_EXT_MAPPING_UFS)
- #define IS_FLASH_ADDRESS(address) (HAL_FLASH_DEVICE_NAME(address) == DRV_NAME_SPI_FLASH || HAL_FLASH_DEVICE_NAME(address) == DRV_NAME_SPI_FLASH_EXT)
- #else
- #define IS_FLASH_ADDRESS(address) (HAL_FLASH_DEVICE_NAME(address) == DRV_NAME_SPI_FLASH)
- #endif
- #ifdef QUEC_PATCH_FACTORY_UPDATE
- bool g_upgrade_by_factory = false;
- #endif
- enum
- {
- FS_PREPARE_WRITE_PHASECHEK,
- FS_PREPARE_WRITE_FIXEDNV,
- FS_PREPARE_WRITE_PREPACK,
- FS_PREPARE_READ_PHASECHECK,
- FS_PREPARE_READ_FIXEDNV,
- FS_PREPARE_ERASE_RUNNINGNV,
- FS_PREPARE_ERASE_PHASECHECK,
- FS_PREPARE_ERASE_APPIMG_FILE,
- FS_PREPARE_BACKUP_PHASE_CHECK,
- };
- typedef struct
- {
- cpioStream_t *cpio;
- fdlDataDnld_t dnld;
- bool phasecheck_backed;
- bool secure_boot_enable;
- bool delay_poweroff;
- bool flash_write_whole;
- bool fixednv_written;
- unsigned device_type;
- fdlChannel_t *channel;
- unsigned max_packet_len;
- osiElapsedTimer_t connect_timer;
- phaseCheckHead_t phasecheck_back;
- char work_mem[WORKMEM_SIZE];
- char fixednv_write_data[CONFIG_NVBIN_FIXED_SIZE];
- unsigned fixednv_write_size;
- unsigned fixednv_read_size;
- char *flash_mem;
- } fdlContext_t;
- /**
- * Mount factory partition
- */
- static bool prvMountFactory(fdlContext_t *d)
- {
- if (!fsMountFsPath(CONFIG_FS_FACTORY_MOUNT_POINT, false))
- return false;
- return true;
- }
- #ifdef CONFIG_QUEC_PROJECT_FEATURE
- /**
- * Mount modem partition
- */
- bool prvMountModem(fdlContext_t *d)
- {
- #ifdef CONFIG_FS_MODEM_MOUNT_POINT
- return fsMountFsPath(CONFIG_FS_MODEM_MOUNT_POINT, false);
- #else
- return true;
- #endif
- }
- /**
- * Mount sys partition
- */
- bool prvMountSys(fdlContext_t *d)
- {
- #ifdef CONFIG_FS_SYS_MOUNT_POINT
- return fsMountFsPath(CONFIG_FS_SYS_MOUNT_POINT, false);
- #else
- return true;
- #endif
- }
- /*
- Attention:
- do not modify in csdk
- */
- const char* g_version_model[] = {
- #if defined(CONFIG_QL_PROJECT_DEF_EC800G_CN_GA)
- "EC800GCNGA",
- #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)
- "EC800GCNLD",
- "EG800GEULD",
- "EC800GCNMD",
- #elif defined(CONFIG_QL_PROJECT_DEF_EC800G_CN_LB) || defined(CONFIG_QL_PROJECT_DEF_EG800G_CN_GB)
- "EC800GCNLB",
- "EG800GCNGB",
- #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)\
- || defined(CONFIG_QL_PROJECT_DEF_EC600G_CN_MC) || defined(CONFIG_QL_PROJECT_DEF_EC600G_CN_CC)
- "EC600GCNLC",
- "EC600GCNLD",
- "EC600GCNMD",
- "EC600GCNCD",
- "EC600GCNMC",
- "EC600GCNCC",
- #elif defined(CONFIG_QL_PROJECT_DEF_EC600G_CN_LA)
- "EC600GCNLA",
- #elif defined(CONFIG_QL_PROJECT_DEF_EC600G_CN_GA)
- "EC600GCNGA",
- #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)
- "EG700GCNLC",
- "EG700GCNLD",
- "EG700GCNMD",
- "EG700GCNND",
- #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)
- "EC200GCNLE",
- "EC200GCNLC",
- "EC200GCNGD",
- #elif defined(CONFIG_QL_PROJECT_DEF_EC200G_CN_LF)
- "EC200GCNLF",
- #endif
- };
- unsigned char g_version_model_size = sizeof(g_version_model) / sizeof(char *);
- extern bool ql_prv_version_model_verify(void);
- #endif
- /**
- * Prepare file system for various senario
- */
- static bool prvFsPrepare(fdlContext_t *d, unsigned kind)
- {
- switch (kind)
- {
- case FS_PREPARE_WRITE_PHASECHEK:
- case FS_PREPARE_WRITE_FIXEDNV:
- return fsMountWithFormatAll();
- case FS_PREPARE_WRITE_PREPACK:
- case FS_PREPARE_ERASE_RUNNINGNV:
- case FS_PREPARE_ERASE_APPIMG_FILE:
- case FS_PREPARE_READ_PHASECHECK:
- case FS_PREPARE_ERASE_PHASECHECK:
- case FS_PREPARE_READ_FIXEDNV:
- fsMountAll(); // ignore error
- return prvMountFactory(d);
- default:
- return false;
- }
- }
- /**
- * BSL_CMD_CONNECT, the timestamp is recorded.
- */
- static void prvConnect(fdlEngine_t *fdl, fdlContext_t *d)
- {
- OSI_LOGI(0x10009061, "FDL: connect");
- osiElapsedTimerStart(&d->connect_timer);
- fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
- }
- /**
- * Flash download start. The common information start/total/received has
- * already initialized. Return response error code.
- */
- static int prvFlashStart(fdlContext_t *d)
- {
- fdlDataDnld_t *dn = &d->dnld;
- // Though it doesn't look reasonable, unaligned start address is supported.
- // In this case, the write address is not the same as erase address.
- dn->write_address = dn->start_address;
- dn->erase_address = OSI_ALIGN_DOWN(dn->start_address, FLASH_SECTOR_SIZE);
- unsigned faddress = HAL_FLASH_OFFSET(dn->erase_address);
- unsigned fend = HAL_FLASH_OFFSET(OSI_ALIGN_UP(dn->start_address + dn->total_size, FLASH_SECTOR_SIZE));
- int esize = bootSpiFlashEraseNoWait(dn->flash, faddress, fend - faddress);
- OSI_LOGV(0x10009062, "FDL2 flash erase no wait 0x%x/0x%x/%d", faddress, fend - faddress, esize);
- if (esize < 0)
- {
- dn->flash_stage = FLASH_STAGE_NONE;
- OSI_LOGE(0x10009063, "FDL: flash start failed 0x%x/0x%x", dn->start_address, dn->total_size);
- return -BSL_REP_DOWN_DEST_ERROR;
- }
- dn->erase_address += esize;
- dn->flash_stage = FLASH_STAGE_ERASE;
- dn->data_verify = crc32Init();
- return 0;
- }
- /**
- * Flash polling, called in FDL polling, midst and end. Don't access
- * \p dnld.received_size, rather the parameter should be used.
- */
- static void prvFlashPolling(fdlContext_t *d, unsigned received)
- {
- fdlDataDnld_t *dn = &d->dnld;
- if (dn->flash_stage == FLASH_STAGE_NONE ||
- dn->flash_stage == FLASH_STAGE_FINISH)
- return;
- if (dn->flash_stage == FLASH_STAGE_ERASE)
- {
- if (!bootSpiFlashIsDone(dn->flash))
- return;
- dn->flash_stage = FLASH_STAGE_WAIT_DATA;
- }
- else if (dn->flash_stage == FLASH_STAGE_WAIT_DATA)
- {
- int avail = received - (dn->write_address - dn->start_address);
- if (avail < FLASH_PAGE_SIZE || dn->write_address >= dn->erase_address)
- return;
- unsigned waddress = HAL_FLASH_OFFSET(dn->write_address);
- void *wdata = &d->work_mem[dn->write_address % WORKMEM_SIZE];
- int wsize = bootSpiFlashWriteNoWait(dn->flash, waddress, wdata, FLASH_PAGE_SIZE);
- OSI_LOGV(0x10009064, "FDL2 flash write no wait 0x%x/0x%x", waddress, wsize);
- dn->write_address += wsize;
- dn->flash_stage = FLASH_STAGE_WRITE;
- }
- else if (dn->flash_stage == FLASH_STAGE_WRITE)
- {
- if (!bootSpiFlashIsDone(dn->flash))
- return;
- if (dn->write_address < dn->erase_address)
- {
- dn->flash_stage = FLASH_STAGE_WAIT_DATA;
- return;
- }
- unsigned faddress = HAL_FLASH_OFFSET(dn->erase_address);
- unsigned fend = HAL_FLASH_OFFSET(OSI_ALIGN_UP(dn->start_address + dn->total_size, FLASH_SECTOR_SIZE));
- if (faddress >= fend)
- {
- dn->flash_stage = FLASH_STAGE_FINISH;
- return;
- }
- int esize = bootSpiFlashEraseNoWait(dn->flash, faddress, fend - faddress);
- OSI_LOGV(0x10009062, "FDL2 flash erase no wait 0x%x/0x%x/%d", faddress, fend - faddress, esize);
- dn->erase_address += esize;
- dn->flash_stage = FLASH_STAGE_ERASE;
- }
- }
- /**
- * Flash midst
- */
- static void prvFlashMidst(fdlContext_t *d, const void *data, unsigned size)
- {
- fdlDataDnld_t *dn = &d->dnld;
- dn->data_verify = crc32Update(dn->data_verify, data, size);
- // work_mem is reused as ring buffer. The index is address rather than
- // size. So, page write can always use linear buffer.
- unsigned mem_pos = (dn->start_address + dn->received_size) % WORKMEM_SIZE;
- unsigned tail = WORKMEM_SIZE - mem_pos;
- if (tail >= size)
- {
- memcpy(&d->work_mem[mem_pos], data, size);
- }
- else
- {
- memcpy(&d->work_mem[mem_pos], data, tail);
- memcpy(&d->work_mem[0], (const char *)data + tail, size - tail);
- }
- // Polling to make sure there are room for the next packet data.
- unsigned received = dn->received_size + size;
- unsigned received_address = dn->start_address + dn->received_size + size;
- while (received_address - dn->write_address > WORKMEM_SIZE - d->max_packet_len)
- prvFlashPolling(d, received);
- }
- /**
- * Flash end, write the remaining data and check crc.
- */
- static int prvFlashEnd(fdlContext_t *d)
- {
- fdlDataDnld_t *dn = &d->dnld;
- // size may be unaligned. So, polling to make sure the remaining data
- // less than a page.
- unsigned received_address = dn->start_address + dn->received_size;
- while (dn->write_address + FLASH_PAGE_SIZE <= received_address)
- prvFlashPolling(d, dn->received_size);
- // Write the remaining data, if exists.
- bootSpiFlashWaitDone(dn->flash);
- int remained = received_address - dn->write_address;
- if (remained > 0)
- {
- // It is possible that the remaining are located at unerased sector
- unsigned faddress = HAL_FLASH_OFFSET(dn->erase_address);
- unsigned fend = HAL_FLASH_OFFSET(OSI_ALIGN_UP(dn->start_address + dn->total_size, FLASH_SECTOR_SIZE));
- if (faddress < fend)
- {
- int esize = bootSpiFlashErase(dn->flash, faddress, fend - faddress);
- OSI_LOGV(0x10009065, "FDL2 flash erase 0x%x/0x%x/%d", faddress, fend - faddress, esize);
- dn->erase_address += esize;
- }
- unsigned waddress = HAL_FLASH_OFFSET(dn->write_address);
- void *wdata = &d->work_mem[dn->write_address % WORKMEM_SIZE];
- bootSpiFlashWrite(dn->flash, waddress, wdata, remained);
- OSI_LOGV(0x10009066, "FDL2 flash write 0x%x/0x%x", waddress, remained);
- }
- unsigned fstart = HAL_FLASH_OFFSET(dn->start_address);
- const void *fptr = bootSpiFlashMapAddress(dn->flash, fstart);
- unsigned fverify = crc32Calc(fptr, dn->total_size);
- dn->flash_stage = FLASH_STAGE_NONE;
- dn->flash = NULL;
- if (fverify != dn->data_verify)
- {
- OSI_LOGE(0x10009067, "FDL2 flash crc error, start/0x%x size/0x%x crc/0x%x calc/0x%x",
- dn->start_address, dn->total_size, dn->data_verify, fverify);
- return -BSL_REP_VERIFY_ERROR;
- }
- return 0;
- }
- /**
- * Write flash after all data received.
- */
- static int prvFlashWhole(fdlContext_t *d)
- {
- unsigned start_addr = d->dnld.start_address;
- if (d->secure_boot_enable)
- {
- // flash image signature check
- if (!bootSimageCheckSign((const simageHeader_t *)(d->flash_mem)))
- {
- return -BSL_REP_SEC_VERIFY_ERROR;
- }
- }
- unsigned end_addr = start_addr + d->dnld.total_size;
- unsigned erase_offset = OSI_ALIGN_DOWN(HAL_FLASH_OFFSET(start_addr), FLASH_SECTOR_SIZE);
- unsigned erase_size = OSI_ALIGN_UP(HAL_FLASH_OFFSET(end_addr) - erase_offset, FLASH_SECTOR_SIZE);
- unsigned write_offset = HAL_FLASH_OFFSET(start_addr);
- unsigned write_size = d->dnld.total_size;
- if (!bootSpiFlashErase(d->dnld.flash, erase_offset, erase_size))
- return -BSL_REP_VERIFY_ERROR;
- if (!bootSpiFlashWrite(d->dnld.flash, write_offset, d->flash_mem, write_size))
- return -BSL_REP_VERIFY_ERROR;
- return 0;
- }
- /**
- * Post check after progressive flash write.
- */
- static int prvFlashPostCheck(fdlContext_t *d)
- {
- // The followings are only for secure boot
- if (!d->secure_boot_enable)
- return 0;
- if (!bootSimageCheckSign((const simageHeader_t *)(d->dnld.start_address)))
- {
- return -BSL_REP_SEC_VERIFY_ERROR;
- }
- return 0;
- }
- /**
- * Write one file from cpio.
- */
- static void prvPackageFile(cpioFile_t *f)
- {
- char name[VFS_PATH_MAX + 1] = "/";
- bool isdir = f->mode & S_IFDIR;
- memcpy(name + 1, f->name, strlen(f->name) + 1);
- #ifdef CONFIG_QUEC_PROJECT_FEATURE
- #ifdef CONFIG_QUEC_PROJECT_FEATURE_BOOT_FAT_RW
- QUEC_BOOT_LOG("package file %s (%d/%u)", name, isdir, f->data_size);
- #endif
- if(strncmp(name, CONFIG_FS_SPI4_EXT_NOR_SFFS_MOUNT_POINT, 6) == 0)
- {
- #ifdef CONFIG_QUEC_PROJECT_FEATURE_BOOT_SPI4_EXTNSFFS
- if(!quec_spi4_exnsffs_is_mount())
- {
- goto exit;
- }
- #else
- goto exit;
- #endif
- }
- else if(strncmp(name, CONFIG_FS_SPI6_EXT_NOR_SFFS_MOUNT_POINT, 4) == 0)
- {
- #ifdef CONFIG_QUEC_PROJECT_FEATURE_SPI6_EXT_NOR
- extern bool quec_spi6_ext_norflash_get_mount_status(void);
- if(!quec_spi6_ext_norflash_get_mount_status())
- {
- goto exit;
- }
- #else
- goto exit;
- #endif
- }
- else if(strncmp(name, CONFIG_FS_SDCARD_MOUNT_POINT, 7) == 0) //"/sdcard0" || "/sdcard1"
- {
- #ifdef CONFIG_QUEC_PROJECT_FEATURE_BOOT_FAT_RW
- char *file_name = name + 8; //skip "/sdcard0" || "/sdcard1"
- ql_boot_fat_mount_pt_e pt = (name[7] == '0') ? QL_BOOT_FAT_MOUNT_PARTITION_1 : QL_BOOT_FAT_MOUNT_PARTITION_2;
- if(ql_boot_fat_open_ex(pt,file_name,QL_BOOT_FAT_OPEN_CREATE) == 0) //Only new and read files are supported
- {
- if(ql_boot_fat_write_ex (pt,(const void*)f->data, f->data_size) != f->data_size) //Write data to a file
- {
- QUEC_BOOT_LOG("%s download failed",name);
- return;
- }
- ql_boot_fat_close_ex (pt);
- return;
- }
- QUEC_BOOT_LOG("%s open failed",name);
- return;
- #else
- goto exit;
- #endif
- }
- #endif/* CONFIG_QUEC_PROJECT_FEATURE */
- OSI_LOGXI(OSI_LOGPAR_SII, 0, "package file %s (%d/%u)", name, isdir, f->data_size);
- if (isdir)
- {
- vfs_mkpath(name, 0);
- }
- else
- {
- vfs_mkfilepath(name, 0);
- vfs_file_write(name, f->data, f->data_size);
- }
- #ifdef CONFIG_QUEC_PROJECT_FEATURE
- return;
- exit:
- QUEC_BOOT_LOG("%s is not ready to down file",name);
- #endif
- }
- /**
- * BSL_CMD_START_DATA, return non-zero if response needed
- * When file system access is needed, it should be chcked here.
- */
- static int prvDataStart(fdlEngine_t *fdl, fdlPacket_t *pkt, fdlContext_t *d)
- {
- int result = 0;
- uint32_t *ptr = (uint32_t *)pkt->content;
- uint32_t start_addr = OSI_FROM_BE32(*ptr++);
- uint32_t file_size = OSI_FROM_BE32(*ptr++);
- OSI_LOGI(0x10009068, "FDL: data start, start_addr/0x%x, size/0x%x", start_addr, file_size);
- d->dnld.start_address = start_addr;
- d->dnld.total_size = file_size;
- d->dnld.received_size = 0;
- d->dnld.stage = SYS_STAGE_START;
- if (start_addr == PHASECHECK_LOGIC_ADDRESS)
- {
- #ifdef QUEC_PATCH_FACTORY_UPDATE
- g_upgrade_by_factory = true;
- #endif
- if (file_size != sizeof(phaseCheckHead_t))
- return BSL_REP_DOWN_SIZE_ERROR;
- if (!prvFsPrepare(d, FS_PREPARE_WRITE_PHASECHEK))
- return BSL_REP_INCOMPATIBLE_PARTITION;
- return BSL_REP_ACK;
- }
- if (start_addr == FIXNV_LOGIC_ADDRESS)
- {
- if (file_size > CONFIG_NVBIN_FIXED_SIZE)
- return BSL_REP_DOWN_SIZE_ERROR;
- if (!prvFsPrepare(d, FS_PREPARE_WRITE_FIXEDNV))
- return BSL_REP_INCOMPATIBLE_PARTITION;
- return BSL_REP_ACK;
- }
- if (start_addr == PRE_PACK_FILE_LOGIC_ADDRESS)
- {
- if (!prvFsPrepare(d, FS_PREPARE_WRITE_PREPACK))
- return BSL_REP_INCOMPATIBLE_PARTITION;
- cpioStreamCfg_t cfg = {
- .file_size_max = PACKAGE_FILE_MAX_SIZE,
- .file_path_max = VFS_PATH_MAX,
- };
- d->cpio = cpioStreamCreate(&cfg);
- if (d->cpio == NULL)
- return BSL_PHONE_NOT_ENOUGH_MEMORY;
- return BSL_REP_ACK;
- }
- if (IS_FLASH_ADDRESS(start_addr))
- {
- bootSpiFlash_t *flash = bootSpiFlashOpen(HAL_FLASH_DEVICE_NAME(start_addr));
- if (flash == NULL)
- return BSL_REP_OPERATION_FAILED;
- d->dnld.flash = flash;
- d->flash_write_whole = false;
- if (start_addr == CONFIG_SPL_FLASH_ADDRESS)
- d->flash_write_whole = true;
- if (d->secure_boot_enable)
- {
- #ifdef CONFIG_FDL_FLASH_SIGCHECK_BEFORE_WRITE
- if (start_addr == CONFIG_APP_FLASH_ADDRESS ||
- start_addr == CONFIG_APPIMG_FLASH_ADDRESS)
- d->flash_write_whole = true;
- #endif
- }
- if (d->flash_write_whole)
- {
- d->flash_mem = malloc(d->dnld.total_size);
- if (d->flash_mem == NULL)
- return BSL_PHONE_NOT_ENOUGH_MEMORY;
- }
- else
- {
- if ((result = prvFlashStart(d)) < 0)
- return -result;
- }
- return BSL_REP_ACK;
- }
- return BSL_REP_DOWN_DEST_ERROR;
- }
- /**
- * BSL_CMD_MIDST_DATA, return non-zero if response needed
- */
- static int prvDataMidst(fdlEngine_t *fdl, fdlPacket_t *pkt, fdlContext_t *d)
- {
- uint16_t data_len = pkt->size;
- uint32_t start_addr = d->dnld.start_address;
- OSI_LOGD(0x10009069, "FDL: data midst, start_addr/0x%x, size/0x%x, received/0x%x, len/0x%x, stage/0x%x",
- d->dnld.start_address, d->dnld.total_size, d->dnld.received_size,
- data_len, d->dnld.stage);
- if ((d->dnld.stage != SYS_STAGE_START) && (d->dnld.stage != SYS_STAGE_GATHER))
- {
- d->dnld.flash_stage = FLASH_STAGE_NONE;
- d->dnld.flash = NULL;
- return BSL_REP_DOWN_NOT_START;
- }
- if (d->dnld.received_size + data_len > d->dnld.total_size)
- {
- d->dnld.flash_stage = FLASH_STAGE_NONE;
- d->dnld.flash = NULL;
- return BSL_REP_DOWN_SIZE_ERROR;
- }
- d->dnld.stage = SYS_STAGE_GATHER;
- if (start_addr == PRE_PACK_FILE_LOGIC_ADDRESS)
- {
- #ifdef __QUEC_OEM_VER_TY__
- static bool isClear = false;
- if (isClear == false)
- {
- vfs_rmchildren(CONFIG_FS_SYS_MOUNT_POINT);
- isClear = true;
- }
- #endif
- cpioStreamPushData(d->cpio, pkt->content, data_len);
- cpioFile_t *f;
- while ((f = cpioStreamPopFile(d->cpio)))
- {
- #if defined(CONFIG_APPIMG_LOAD_FILE)
- if (d->secure_boot_enable && strcmp(f->name, &CONFIG_APPIMG_LOAD_FILE_NAME[1]) == 0)
- {
- OSI_LOGI(0x1000906a, "FDL: appimg file verify size %d", f->data_size);
- // TODO: appimg signature check
- }
- #endif
- prvPackageFile(f);
- cpioStreamDestroyFile(d->cpio, f);
- }
- d->dnld.received_size += data_len;
- return BSL_REP_ACK;
- }
- if (IS_FLASH_ADDRESS(start_addr))
- {
- if (d->flash_write_whole)
- memcpy(&d->flash_mem[0] + d->dnld.received_size, pkt->content, data_len);
- else
- prvFlashMidst(d, pkt->content, data_len);
- d->dnld.received_size += data_len;
- return BSL_REP_ACK;
- }
- if (d->dnld.received_size + data_len > WORKMEM_SIZE)
- return BSL_REP_DOWN_SIZE_ERROR;
- memcpy(&d->work_mem[0] + d->dnld.received_size, pkt->content, data_len);
- d->dnld.received_size += data_len;
- return BSL_REP_ACK;
- }
- /**
- * BSL_CMD_END_DATA, return non-zero if response needed
- */
- static int prvDataEnd(fdlEngine_t *fdl, fdlContext_t *d)
- {
- int result = 0;
- uint32_t start_addr = d->dnld.start_address;
- OSI_LOGI(0x1000906b, "FDL: data end, start_addr/0x%x, size/0x%x, received/0x%x, stage/0x%x",
- d->dnld.start_address, d->dnld.total_size, d->dnld.received_size,
- d->dnld.stage);
- if ((d->dnld.stage != SYS_STAGE_START) && (d->dnld.stage != SYS_STAGE_GATHER))
- {
- d->dnld.flash_stage = FLASH_STAGE_NONE;
- d->dnld.flash = NULL;
- return BSL_REP_DOWN_NOT_START;
- }
- if (d->dnld.received_size != d->dnld.total_size)
- {
- d->dnld.flash_stage = FLASH_STAGE_NONE;
- d->dnld.flash = NULL;
- return BSL_REP_DOWN_SIZE_ERROR;
- }
- d->dnld.stage = SYS_STAGE_END;
- if (start_addr == PHASECHECK_LOGIC_ADDRESS)
- {
- phaseCheckHead_t *phase_check = (phaseCheckHead_t *)&d->work_mem[0];
- if (!nvmWritePhaseCheck(phase_check))
- return BSL_REP_OPERATION_FAILED;
- return BSL_REP_ACK;
- }
- if (start_addr == FIXNV_LOGIC_ADDRESS)
- {
- char *nvbin = &d->work_mem[0];
- #ifdef QUEC_PATCH_FACTORY_UPDATE
- if (nvmWriteFixedBin_v2(nvbin, d->dnld.received_size, g_upgrade_by_factory) < 0)
- #else
- if (nvmWriteFixedBin(nvbin, d->dnld.received_size) < 0)
- #endif
- {
- return BSL_REP_OPERATION_FAILED;
- }
- d->fixednv_write_size = d->dnld.received_size;
- memcpy(d->fixednv_write_data, nvbin, d->fixednv_write_size);
- if (d->phasecheck_backed)
- {
- d->phasecheck_backed = false;
- if (!nvmWritePhaseCheck(&d->phasecheck_back))
- return BSL_REP_OPERATION_FAILED;
- }
- return BSL_REP_ACK;
- }
- if (start_addr == PRE_PACK_FILE_LOGIC_ADDRESS)
- {
- cpioStreamDestroy(d->cpio);
- d->cpio = NULL;
- return BSL_REP_ACK;
- }
- if (IS_FLASH_ADDRESS(start_addr))
- {
- if (d->flash_write_whole)
- {
- d->flash_write_whole = false;
- result = prvFlashWhole(d);
- free(d->flash_mem);
- d->flash_mem = NULL;
- return (result < 0) ? -result : BSL_REP_ACK;
- }
- if ((result = prvFlashEnd(d)) < 0)
- return -result;
- if ((result = prvFlashPostCheck(d)) < 0)
- return -result;
- return BSL_REP_ACK;
- }
- return BSL_REP_INVALID_CMD;
- }
- /**
- * BSL_CMD_NORMAL_RESET
- */
- static void prvResetNormal(fdlEngine_t *fdl, fdlContext_t *d)
- {
- OSI_LOGI(0x1000906c, "FDL: reset to normal");
- fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
- osiDelayUS(2000);
- bootReset(BOOT_RESET_NORMAL);
- }
- /**
- * Polling for delayed poweroff
- */
- static void prvPowerOffPolling(fdlContext_t *d)
- {
- if (!d->delay_poweroff)
- return;
- if (BOOT_DNLD_FROM_UART(d->device_type))
- {
- unsigned ms = osiElapsedTime(&d->connect_timer);
- if (ms > DELAY_POWEROFF_TIMEOUT)
- {
- OSI_LOGI(0x1000906d, "FDL: poweroff timeout", ms);
- bootPowerOff();
- // ideally, we shouldn't come here
- OSI_LOGE(0x1000906e, "FDL: poweroff failed");
- d->delay_poweroff = false;
- }
- }
- if (BOOT_DNLD_FROM_USERIAL(d->device_type))
- {
- if (!d->channel->connected(d->channel))
- {
- OSI_LOGI(0x1000906f, "FDL: device not connected, poweroff");
- bootPowerOff();
- // ideally, we shouldn't come here
- OSI_LOGE(0x1000906e, "FDL: poweroff failed");
- d->delay_poweroff = false;
- }
- }
- }
- /**
- * BSL_CMD_POWER_OFF
- */
- static void prvPowerOff(fdlEngine_t *fdl, fdlContext_t *d)
- {
- OSI_LOGI(0x10009070, "FDL: poweroff");
- d->delay_poweroff = true;
- osiElapsedTimerStart(&d->connect_timer);
- fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
- }
- /**
- * BSL_CMD_READ_FLASH, return non-zero if response needed
- */
- static int prvReadFlash(fdlEngine_t *fdl, fdlPacket_t *pkt, fdlContext_t *d)
- {
- uint32_t *ptr = (uint32_t *)pkt->content;
- uint32_t addr = OSI_FROM_BE32(*ptr++);
- uint32_t size = OSI_FROM_BE32(*ptr++);
- uint32_t offset = OSI_FROM_BE32(*ptr++); // not all address has this parameter
- if (offset == 0)
- OSI_LOGI(0x10009071, "FDL: read flash, addr/0x%x, size/0x%x, offset/0x%x", addr, size, offset);
- if (addr == PHASECHECK_LOGIC_ADDRESS)
- {
- if (!prvFsPrepare(d, FS_PREPARE_READ_PHASECHECK))
- return BSL_REP_INCOMPATIBLE_PARTITION;
- // reuse the working memory
- phaseCheckHead_t *phase_check = (phaseCheckHead_t *)&d->work_mem[0];
- memset(phase_check, 0, sizeof(phaseCheckHead_t));
- if (!nvmReadPhasecheck(phase_check))
- return BSL_REP_OPERATION_FAILED;
- fdlEngineSendRespData(fdl, BSL_REP_READ_FLASH, phase_check, sizeof(phaseCheckHead_t));
- return 0; // already send response
- }
- if (addr == FIXNV_LOGIC_ADDRESS)
- {
- // Assuming the read will be started with offset 0, and continuous
- char *nvbin = &d->work_mem[0];
- if (offset == 0)
- {
- if (!prvFsPrepare(d, FS_PREPARE_READ_FIXEDNV))
- return BSL_REP_INCOMPATIBLE_PARTITION;
- memset(nvbin, 0xff, CONFIG_NVBIN_FIXED_SIZE);
- int read_size = 0;
- if (d->fixednv_write_size > 0)
- {
- read_size = nvmReadUpdataFixedBin(d->fixednv_write_data, d->fixednv_write_size);
- if (read_size <= 0)
- return BSL_REP_OPERATION_FAILED;
- memcpy(nvbin, d->fixednv_write_data, read_size);
- }
- else
- {
- read_size = nvmReadFixedBin(nvbin, CONFIG_NVBIN_FIXED_SIZE);
- if (read_size <= 0)
- return BSL_REP_OPERATION_FAILED;
- }
- d->fixednv_read_size = read_size;
- }
- if (offset >= d->fixednv_read_size)
- return BSL_REP_INVALID_CMD;
- unsigned send_size = OSI_MIN(unsigned, d->fixednv_read_size - offset, size);
- fdlEngineSendRespData(fdl, BSL_REP_READ_FLASH, nvbin + offset, send_size);
- return 0; // already send response
- }
- if (IS_FLASH_ADDRESS(addr))
- {
- bootSpiFlash_t *flash = bootSpiFlashOpen(HAL_FLASH_DEVICE_NAME(addr));
- if (flash == NULL)
- return BSL_REP_OPERATION_FAILED;
- // valid flash offset not includes the end address
- if (!bootSpiFlashMapAddressValid(flash, (void *)(addr + size - 1)))
- return BSL_REP_INVALID_CMD;
- uint32_t flash_offset = HAL_FLASH_OFFSET(addr);
- const void *fdata = bootSpiFlashMapAddress(flash, flash_offset);
- fdlEngineSendRespData(fdl, BSL_REP_READ_FLASH, fdata, size);
- return 0; // already send response
- }
- return BSL_REP_INVALID_CMD;
- }
- /**
- * BSL_CMD_ERASE_FLASH, return non-zero if response needed
- */
- static int prvEraseFlash(fdlEngine_t *fdl, fdlPacket_t *pkt, fdlContext_t *d)
- {
- uint32_t *ptr = (uint32_t *)pkt->content;
- uint32_t addr = OSI_FROM_BE32(*ptr++);
- uint32_t size = OSI_FROM_BE32(*ptr++);
- OSI_LOGI(0x10009072, "FDL: erase flash, addr/0x%x, size/0x%x", addr, size);
- if (addr == ERASE_RUNNING_NV_LOGIC_ADDRESS)
- {
- if (!prvFsPrepare(d, FS_PREPARE_ERASE_RUNNINGNV))
- return BSL_REP_INCOMPATIBLE_PARTITION;
- nvmClearRunning(); // ignore error
- return BSL_REP_ACK;
- }
- if (addr == PHASECHECK_LOGIC_ADDRESS)
- {
- if (!prvFsPrepare(d, FS_PREPARE_ERASE_PHASECHECK))
- return BSL_REP_INCOMPATIBLE_PARTITION;
- nvmClearPhaseCheck(); // ignore error
- return BSL_REP_ACK;
- }
- if (addr == DEL_APPIMG_LOGIC_ADDRESS)
- {
- #if defined(CONFIG_APPIMG_LOAD_FLASH) && defined(CONFIG_APPIMG_LOAD_FILE_NAME)
- if (!prvFsPrepare(d, FS_PREPARE_ERASE_APPIMG_FILE))
- return BSL_REP_INCOMPATIBLE_PARTITION;
- vfs_unlink(CONFIG_APPIMG_LOAD_FILE_NAME); // ignore error
- #endif
- return BSL_REP_ACK;
- }
- if (addr == FMT_FLASH_LOGIC_ADDRESS)
- {
- // "size" is the flash block device name
- if (!fsMountFormatFlash(size))
- return BSL_REP_OPERATION_FAILED;
- return BSL_REP_ACK;
- }
- if (FLASH_ERASE_ALL == addr && FLASH_ERASE_ALL_SIZE == size)
- {
- // PC tool won't backup PhaseCheck. We will try to backup PhaseCheck
- // here. And if there is operation to write FIXEDNV, PhaseCheck will
- // be restored there.
- if (prvFsPrepare(d, FS_PREPARE_READ_PHASECHECK) &&
- nvmReadPhasecheck(&d->phasecheck_back))
- d->phasecheck_backed = true;
- fsUmountAll();
- bootSpiFlash_t *flash = bootSpiFlashOpen(DRV_NAME_SPI_FLASH);
- if (flash == NULL)
- return BSL_REP_OPERATION_FAILED;
- bootSpiFlashChipErase(flash);
- #if ((defined CONFIG_BOARD_WITH_EXT_FLASH) || (defined CONFIG_QUEC_PROJECT_FEATURE_SPI6_EXT_NOR) \
- || (defined CONFIG_QUEC_PROJECT_FEATURE_EXT_MAPPING_UFS))
- bootSpiFlash_t *flash_ext = bootSpiFlashOpen(DRV_NAME_SPI_FLASH_EXT);
- #ifndef CONFIG_QUEC_PROJECT_FEATURE
- if (flash_ext == NULL)
- return BSL_REP_OPERATION_FAILED;
- bootSpiFlashChipErase(flash_ext);
- #else
- if(flash_ext != NULL)
- {
- bootSpiFlashChipErase(flash_ext);
- }
- #endif
- #endif
- return BSL_REP_ACK;
- }
- if (IS_FLASH_ADDRESS(addr))
- {
- bootSpiFlash_t *flash = bootSpiFlashOpen(HAL_FLASH_DEVICE_NAME(addr));
- uint32_t flash_offset = HAL_FLASH_OFFSET(addr);
- if (!bootSpiFlashErase(flash, flash_offset, size))
- return BSL_REP_INVALID_CMD;
- return BSL_REP_ACK;
- }
- return BSL_REP_INVALID_CMD;
- }
- /**
- * BSL_CMD_CHANGE_BAUD
- */
- static void prvSetBaud(fdlEngine_t *fdl, fdlPacket_t *pkt, fdlContext_t *d)
- {
- uint32_t *ptr = (uint32_t *)pkt->content;
- uint32_t baud = OSI_FROM_BE32(*ptr++);
- OSI_LOGI(0x10009073, "FDL: change baud %d", baud);
- // This is special, ACK must be sent in old baud rate.
- fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
- fdlEngineSetBaud(fdl, baud);
- }
- /**
- * Process packet, called by engine.
- */
- static void prvProcessPkt(fdlEngine_t *fdl, fdlPacket_t *pkt, void *param)
- {
- if (fdl == NULL || pkt == NULL)
- osiPanic();
- OSI_LOGV(0x10009074, "FDL: pkt type/0x%x, size/0x%x", pkt->type, pkt->size);
- fdlContext_t *d = (fdlContext_t *)param;
- int ret = 0;
- switch (pkt->type)
- {
- case BSL_CMD_CONNECT:
- prvConnect(fdl, d);
- break;
- case BSL_CMD_START_DATA:
- if ((ret = prvDataStart(fdl, pkt, d)) != 0)
- fdlEngineSendRespNoData(fdl, ret);
- break;
- case BSL_CMD_MIDST_DATA:
- if ((ret = prvDataMidst(fdl, pkt, d)) != 0)
- fdlEngineSendRespNoData(fdl, ret);
- break;
- case BSL_CMD_END_DATA:
- if ((ret = prvDataEnd(fdl, d)) != 0)
- fdlEngineSendRespNoData(fdl, ret);
- break;
- case BSL_CMD_NORMAL_RESET:
- prvResetNormal(fdl, d);
- break;
- case BSL_CMD_READ_FLASH:
- if ((ret = prvReadFlash(fdl, pkt, d)) != 0)
- fdlEngineSendRespNoData(fdl, ret);
- break;
- case BSL_CMD_ERASE_FLASH:
- #ifdef CONFIG_QUEC_PROJECT_FEATURE
- if(ql_prv_version_model_verify() == false)
- {
- //BSL_REP_VERIFY_ERROR
- //BSL_REP_UNKNOWN_DEVICE
- fdlEngineSendRespNoData(fdl, BSL_REP_UNKNOWN_DEVICE);
- break;
- }
- #endif
- if ((ret = prvEraseFlash(fdl, pkt, d)) != 0)
- fdlEngineSendRespNoData(fdl, ret);
- break;
- case BSL_CMD_POWER_OFF:
- prvPowerOff(fdl, d);
- break;
- case BSL_CMD_CHANGE_BAUD:
- prvSetBaud(fdl, pkt, d);
- break;
- case BSL_CMD_REPARTITION:
- case BSL_CMD_ENABLE_DEBUG_MODE:
- OSI_LOGI(0x10009075, "FDL: ignore packet type 0x%x", pkt->type);
- fdlEngineSendRespNoData(fdl, BSL_REP_ACK);
- break;
- default:
- OSI_LOGE(0x10009076, "FDL: unkonw packet 0x%x", pkt->type);
- fdlEngineSendRespNoData(fdl, BSL_REP_INVALID_CMD);
- break;
- }
- }
- /**
- * Polling. Called by engine
- */
- static void prvPolling(fdlEngine_t *fdl, void *param)
- {
- fdlContext_t *d = (fdlContext_t *)param;
- prvFlashPolling(d, d->dnld.received_size);
- prvPowerOffPolling(d);
- }
- /**
- * Start download
- */
- static bool prvDnldStart(fdlEngine_t *fdl, unsigned devtype)
- {
- fdlContext_t *d = calloc(1, sizeof(fdlContext_t));
- if (d == NULL)
- return false;
- #if (defined CONFIG_QUEC_PROJECT_FEATURE_SPI6_EXT_NOR) || (defined CONFIG_QUEC_PROJECT_FEATURE_EXT_MAPPING_UFS)
- if(ql_ext_flash_cfg.xip_flag || QUEC_EXT_FLASH_TO_UFS == ql_ext_flash_cfg.ufs_mapping_select)
- {
- halPmuExtFlashPowerOn(); //if use ext flash to run the code or mapping ext flash to UFS,you'll need to initialize it here as well
- }
- #endif
- d->device_type = devtype;
- d->channel = fdlEngineGetChannel(fdl);
- d->max_packet_len = fdlEngineGetMaxPacketLen(fdl);
- d->secure_boot_enable = bootSecureBootEnable();
- fsMountSetScenario(FS_SCENRARIO_FDL);
- //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
- #if (defined CONFIG_APP_FLASH2_ENABLED || defined CONFIG_APPIMG_FLASH2_ENABLED)
- #if (defined CONFIG_QUEC_PROJECT_FEATURE_SPI6_EXT_NOR)
- extern void ql_boot_set_skip_spi6_ext_norflash_init(bool onff);
- if(ql_ext_flash_cfg.xip_flag && QUEC_EXT_FLASH_TO_UFS != ql_ext_flash_cfg.ufs_mapping_select)
- {
- if(ql_ext_flash_cfg.mount_sffs_flag)
- {
- OSI_LOGE(0, "demo: boot not skip ext spi6 norflash");
- ql_boot_set_skip_spi6_ext_norflash_init(false);
- }
- }
- #endif
- #else
- #if 0
- /*
- If you want to down file to ext spi6 nor flash, you can open this code to mount it,
- then the file will be download to ext spi6 nor flash
- */
- #ifdef CONFIG_QUEC_PROJECT_FEATURE_SPI6_EXT_NOR
- if(!ql_ext_flash_cfg.xip_flag && QUEC_EXT_FLASH_TO_UFS != ql_ext_flash_cfg.ufs_mapping_select)
- {
- halPmuExtFlashPowerOn();
- extern void ql_boot_set_skip_spi6_ext_norflash_init(bool onff);
- OSI_LOGE(0, "demo: boot not skip ext spi6 norflash");
- ql_boot_set_skip_spi6_ext_norflash_init(false);
- }
- #endif
- #endif
- #endif
- #if 0
- /*
- If you want to down file to extn spi4 nor flash, you can open this code to mount it,
- then the file will be download to extn spi4 nor flash
- */
- #ifdef CONFIG_QUEC_PROJECT_FEATURE_BOOT_SPI4_EXTNSFFS
- ql_boot_spi4_nor_flash_init(); //Initial spi4 nor Flash
- if(fsMountGeneralSpiFlash(false)) //Mount the SFFS file system
- {
- //Whether to format if the mount fails
- //fsMountGeneralSpiFlash(true); //Format the SFFS file system
- }
- #endif
- #endif
- #if 0
- /*
- If you want to down file to sdmmc, you can open this code to init sdmmc & mount it,
- then the file will be download to "/sdcard0"
- */
- #ifdef CONFIG_QUEC_PROJECT_FEATURE_BOOT_FAT_RW
- //SDMMC1
- #if (defined CONFIG_QUEC_PROJECT_FEATURE_BOOT_SDMMC)
- //挂载预置文件的路径选择,可以同时挂载两个分区
- ql_boot_sdmmc_cfg.power_mv = POWER_LEVEL_3200MV; //default sdcard voltage is 3.2 V
- ql_boot_sdmmc_cfg.sdmmc_clk = QL_BOOT_SDMMC_CLK_FREQ_SDHC; //400000 <= freq <= 50000000,
- //default sdcard clk is 50MHz(SDHC) or 25MHz(NOT SDHC).
- quec_boot_sdmmc_init_ex(QL_BOOT_FAT_MOUNT_PARTITION_1); // "/sdcard0" 挂载分区1,如果没有分区,默认分区1
- //quec_boot_sdmmc_init_ex(QL_BOOT_FAT_MOUNT_PARTITION_2); // "/sdcard1" 挂载分区2
- #elif (defined CONFIG_QUEC_PROJECT_FEATURE_BOOT_EMMC)
- //挂载预置文件的路径选择,可以同时挂载两个分区
- ql_boot_sdmmc_cfg.power_mv = POWER_LEVEL_1800MV; //default emmc voltage is 1.8 V
- ql_boot_sdmmc_cfg.sdmmc_clk = QL_BOOT_SDMMC_CLK_FREQ_SD; //default emmc clk is 25MHz
- quec_boot_emmc_init_ex(QL_BOOT_FAT_MOUNT_PARTITION_1); // "/sdcard0" 挂载分区1,如果没有分区,默认分区1
- //quec_boot_emmc_init_ex(QL_BOOT_FAT_MOUNT_PARTITION_2); // "/sdcard1" 挂载分区2
- //SDMMC2
- #elif (defined CONFIG_QUEC_PROJECT_FEATURE_BOOT_SDMMC2)
- ql_boot_sdmmc_cfg.sdmmc_clk = QL_BOOT_SDMMC_CLK_FREQ_SDHC; //400000 <= freq <= 50000000,
- //default sdcard clk is 50MHz(SDHC) or 25MHz(NOT SDHC).
- quec_boot_sdmmc2_init_ex(QL_BOOT_FAT_MOUNT_PARTITION_1); // "/sdcard0" 挂载分区1,如果没有分区,默认分区1
- //quec_boot_emmc2_init_ex(QL_BOOT_FAT_MOUNT_PARTITION_2); // "/sdcard1" 挂载分区2
- #elif (defined CONFIG_QUEC_PROJECT_FEATURE_BOOT_EMMC2)
- ql_boot_sdmmc_cfg.sdmmc_clk = QL_BOOT_SDMMC_CLK_FREQ_SD; //default emmc clk is 25MHz
- quec_boot_emmc2_init_ex(QL_BOOT_FAT_MOUNT_PARTITION_1); // "/sdcard0" 挂载分区1,如果没有分区,默认分区1
- //quec_boot_emmc2_init_ex(QL_BOOT_FAT_MOUNT_PARTITION_2); // "/sdcard1" 挂载分区2
- #endif /* CONFIG_QUEC_PROJECT_FEATURE_BOOT_SDMMC */
- #endif /* CONFIG_QUEC_PROJECT_FEATURE_BOOT_FAT_RW */
- #endif
- #if 0
- /*
- If you want to format user file system when download firmware, you can open this code to do it,
- it will delete all files at the flash partition which for file system.
-
- 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.
- */
- fsMountFormat(CONFIG_FS_SYS_MOUNT_POINT);
- #endif
- #ifdef CONFIG_QUEC_PROJECT_FEATURE
- //20220304 Mount the file system before doing the following,only 8850
- #ifdef CONFIG_SOC_8850
- prvFsPrepare(d, FS_PREPARE_READ_PHASECHECK);
- #endif
- #endif
- //20221012 modified by ryan.yi。将TTS和GNSS宏控改成QUECTEL宏控。无论TTS和GNSS宏控是否打开,烧录时,默认删除预置文件
- #ifdef CONFIG_QUEC_PROJECT_FEATURE
- vfs_unlink(TTS_PREPACK_FILE_PATH);
- //20210926 之前的版本英文TTS使用此文件名,后续TTS资源文件名将统一使用TTS_PREPACK_FILE_PATH
- vfs_unlink(TTS_EN_PREPACK_FILE_PATH);
- //ryan.yi added 20220217 tts资源文件拆分成多个资源文件
- vfs_unlink(QL_TTS_RESOURCE_APPEND_BIN);
- vfs_unlink(QL_TTS_RESOURCE_END_BIN);
- int i =0;
- char tts_append_name[256] = {0};
- for (i=0; i<QL_TTS_RESOURCE_PACKET_MAX; i++)
- {
- //只是用来先确定有没有预置文件要合并
- memset(tts_append_name, 0x00, sizeof(tts_append_name));
- snprintf(tts_append_name, sizeof(tts_append_name), "/qsfs/quectel_pcm_resource_%02d.bin", i);
- vfs_unlink(tts_append_name);
- }
- #endif
- #ifdef CONFIG_QUEC_PROJECT_FEATURE
- vfs_unlink(GNSS_BOOT_FILE_PATH);
- vfs_unlink(GNSS_FIRM_FILE_PATH);
- #endif
- #ifdef CONFIG_QUEC_PROJECT_FEATURE
- //When downloading, the FOTA stage file is deleted by default, prevent repeated restart failure caused by downloading the file during FOTA upgrade
- vfs_unlink(FUPDATE_STAGE_FILE_NAME);
- #endif
- fdlEngineProcess(fdl, prvProcessPkt, prvPolling, d);
- free(d);
- return false;
- }
- #ifdef CONFIG_CHIP_8850_V3_BOARD
- void FdlbootSetUartIomux()
- {
- /*
- hwp_iomux->gpio_16 = 0x18; //UART2
- hwp_iomux->uart_2_cts = 0x10; // UART_4_RX
- hwp_iomux->pad_uart_2_cts &= ~IOMUX_PAD_UART_2_CTS_DRV(0x3);
- hwp_iomux->uart_2_rts = 0x10; // UART_4_TX
- hwp_iomux->pad_uart_2_cts |= IOMUX_PAD_UART_2_CTS_DRV(2);
- hwp_iomux->pad_uart_2_cts &= ~IOMUX_WPU;
- hwp_iomux->pad_uart_2_cts |= IOMUX_WPU;
- hwp_iomux->pad_uart_2_rts &= ~IOMUX_PAD_UART_2_RTS_DRV(0x3);
- hwp_iomux->pad_uart_2_rts |= IOMUX_PAD_UART_2_RTS_DRV(2);
- */
- hwp_iomux->gpio_2 = 0x1c; //UART2_cts
- hwp_iomux->keyout_4 = 0xc; // UART_4_RX
- hwp_iomux->keyout_5 = 0xc; // UART_4_TX
- hwp_iomux->keyout_4 &= ~IOMUX_PAD_KEYOUT_4_DRV(0x3);
- hwp_iomux->keyout_4 |= IOMUX_PAD_KEYOUT_4_DRV(2);
- hwp_iomux->keyout_4 &= ~IOMUX_WPU;
- hwp_iomux->keyout_4 |= IOMUX_WPU;
- hwp_iomux->keyout_5 &= ~IOMUX_PAD_KEYOUT_5_DRV(0x3);
- hwp_iomux->keyout_5 |= IOMUX_PAD_KEYOUT_5_DRV(2);
- }
- #endif
- void bootStart(uint32_t param)
- {
- OSI_CLEAR_SECTION(bss);
- halClockInit(HAL_CLOCK_INIT_FDL);
- halRamInit();
- bootMmuEnable();
- __FPU_Enable();
- _impure_ptr = _GLOBAL_REENT;
- extern uint32_t __sram_heap_start[];
- extern uint32_t __sram_heap_end[];
- extern uint32_t __ram_heap_start[];
- extern uint32_t __ram_heap_end[];
- unsigned sram_heap_size = OSI_PTR_DIFF(__sram_heap_end, __sram_heap_start);
- unsigned ram_heap_size = OSI_PTR_DIFF(__ram_heap_end, __ram_heap_start);
- bootHeapInit(__sram_heap_start, sram_heap_size, __ram_heap_start, ram_heap_size);
- bootHeapDefaultExtRam();
- uint32_t name = DRV_NAME_UART3;
- if (param == ROM_LOADPAR_DOWNLOAD_UART1)
- name = DRV_NAME_UART1;
- else if (param == ROM_LOADPAR_DOWNLOAD_UART2)
- name = DRV_NAME_UART2;
- else if (param == ROM_LOADPAR_DOWNLOAD_UART3)
- name = DRV_NAME_UART3;
- else if (param == ROM_LOADPAR_DOWNLOAD_UART4)
- name = DRV_NAME_UART4;
- else if (param == ROM_LOADPAR_DOWNLOAD_UART5)
- name = DRV_NAME_UART5;
- else if (param == ROM_LOADPAR_DOWNLOAD_UART6)
- name = DRV_NAME_UART6;
- else if (param == ROM_LOADPAR_DOWNLOAD_USERIAL)
- name = DRV_NAME_ACM0;
- bool trace_enable = false;
- #ifdef CONFIG_FDL_LOG_ENABLED
- trace_enable = true;
- #ifdef CONFIG_KERNEL_DIAG_TRACE
- if (name == CONFIG_DIAG_DEFAULT_UART)
- trace_enable = false;
- #endif
- #endif
- #ifdef CONFIG_CHIP_8850_V3_BOARD
- FdlbootSetUartIomux();
- #endif
- bootTraceInit(trace_enable);
- OSI_LOGI(0x1000905c, "FDL: run %x", param);
- halAdiBusInit();
- bootResetPinEnable();
- bootPlatformInit();
- bootGetEfuseCtx();
- bootSpiFlashOpen(DRV_NAME_SPI_FLASH); // ensure accessible
- fdlChannel_t *ch;
- if (name == DRV_NAME_ACM0)
- ch = fdlOpenUsbSerial();
- else
- ch = fdlOpenUart(name, 0, false);
- fdlEngine_t *fdl = fdlEngineCreate(ch, CONFIG_FDL_PACKET_MAX_LEN);
- fdlEngineIdentify(fdl, 0);
- fdlEngineSendVersion(fdl);
- prvDnldStart(fdl, param);
- // never return here
- osiPanic();
- }
|