dl_commands.c 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #include <stdlib.h>
  32. #include <app.h>
  33. #include <debug.h>
  34. #include <arch/arm.h>
  35. #include <dev/udc.h>
  36. #include <string.h>
  37. #include <kernel/thread.h>
  38. #include <kernel/event.h>
  39. #include <arch/ops.h>
  40. #include <target.h>
  41. #include <platform.h>
  42. #include <platform/mt_reg_base.h>
  43. #include <platform/boot_mode.h>
  44. #include <platform/mtk_wdt.h>
  45. #include <platform/mt_rtc.h>
  46. #include <bootimg.h>
  47. #ifdef MTK_GPT_SCHEME_SUPPORT
  48. #include <platform/partition.h>
  49. #else
  50. #include <mt_partition.h>
  51. #endif
  52. #if !defined(MTK_EMMC_SUPPORT) && !defined(MTK_UFS_SUPPORT)
  53. #include <platform/mtk_nand.h>
  54. #endif
  55. #include <img_info.h>
  56. #include <part_interface.h>
  57. #include <block_generic_interface.h>
  58. /*For gpt update*/
  59. #ifdef MTK_GPT_SCHEME_SUPPORT
  60. #if defined(PLATFORM_FASTBOOT_EMPTY_STORAGE) || defined(MTK_GPT_UPDATE_SUPPORT)
  61. extern part_t *partition;
  62. extern int gpt_partition_table_update(const char *arg, void *data, unsigned sz);
  63. extern int read_gpt(part_t *part);
  64. #endif
  65. #endif
  66. /*For image write*/
  67. #include "sparse_format.h"
  68. #include "dl_commands.h"
  69. #ifdef MTK_MMC_COMBO_DRV
  70. #include <mmc_core.h>
  71. #else
  72. #include <platform/mmc_core.h>
  73. #endif
  74. #include <platform/mt_gpt.h>
  75. #include <platform/errno.h>
  76. #ifdef FASTBOOT_WHOLE_FLASH_SUPPORT
  77. #include "partition_parser.h"
  78. #endif
  79. #include "fastboot.h"
  80. #include "mt_pmic.h"
  81. #include "blockheader.h"
  82. #ifdef MTK_ULTRA_FLASH
  83. #include "transfer.h"
  84. #endif
  85. #ifdef MBLOCK_LIB_SUPPORT
  86. #include <mblock.h>
  87. #endif
  88. #define MODULE_NAME "FASTBOOT_DOWNLOAD"
  89. #define MAX_RSP_SIZE 64
  90. extern void *download_base;
  91. #if defined(MTK_MLC_NAND_SUPPORT) || defined(MTK_TLC_NAND_SUPPORT)
  92. extern unsigned long long download_max;
  93. #else
  94. extern unsigned download_max;
  95. #endif
  96. extern unsigned download_size;
  97. extern unsigned fastboot_state;
  98. /*LXO: !Download related command*/
  99. #define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y)))
  100. #define INVALID_PTN -1
  101. //For test: Display info on boot screen
  102. #define DISPLAY_INFO_ON_LCM
  103. #if (defined(MTK_UFS_SUPPORT) || defined(MTK_EMMC_SUPPORT)) //use another macro.
  104. #define EMMC_TYPE
  105. #else
  106. #define NAND_TYPE
  107. #endif
  108. #if defined(MTK_SPI_NOR_SUPPORT)
  109. #define NOR_TYPE
  110. #endif
  111. extern void video_printf (const char *fmt, ...);
  112. extern int video_get_rows(void);
  113. extern void video_set_cursor(int row, int col);
  114. extern void video_clean_screen(void);
  115. #if defined(MTK_MLC_NAND_SUPPORT) || defined(MTK_TLC_NAND_SUPPORT)
  116. extern int nand_write_img(u64 addr, void *data, u32 img_sz,u64 partition_size,int partition_type);
  117. extern int nand_write_img_ex(u64 addr, void *data, u32 length,u64 total_size, u32 *next_offset, u64 partition_start,u64 partition_size, int img_type);
  118. #else
  119. extern int nand_write_img(u32 addr, void *data, u32 img_sz,u32 partition_size,int partition_type);
  120. extern int nand_write_img_ex(u32 addr, void *data, u32 length,u32 total_size, u32 *next_offset, u32 partition_start,u32 partition_size, int img_type);
  121. #endif
  122. extern u32 gpt4_tick2time_ms (u32 tick);
  123. unsigned start_time_ms;
  124. #define TIME_STAMP gpt4_tick2time_ms(gpt4_get_current_tick())
  125. #define TIME_START {start_time_ms = gpt4_tick2time_ms(gpt4_get_current_tick());}
  126. #define TIME_ELAPSE (gpt4_tick2time_ms(gpt4_get_current_tick()) - start_time_ms)
  127. extern int usb_write(void *buf, unsigned len);
  128. extern int usb_read(void *buf, unsigned len);
  129. extern int sec_dl_permission_chk(const char *part_name, unsigned int *permitted);
  130. extern int sec_format_permission_chk(const char *part_name, unsigned int *permitted);
  131. /* todo: give lk strtoul and nuke this */
  132. static u64 hex2uint64(const char *x)
  133. {
  134. u64 n = 0;
  135. while (*x) {
  136. switch (*x) {
  137. case '0':
  138. case '1':
  139. case '2':
  140. case '3':
  141. case '4':
  142. case '5':
  143. case '6':
  144. case '7':
  145. case '8':
  146. case '9':
  147. n = (n << 4) | (*x - '0');
  148. break;
  149. case 'a':
  150. case 'b':
  151. case 'c':
  152. case 'd':
  153. case 'e':
  154. case 'f':
  155. n = (n << 4) | (*x - 'a' + 10);
  156. break;
  157. case 'A':
  158. case 'B':
  159. case 'C':
  160. case 'D':
  161. case 'E':
  162. case 'F':
  163. n = (n << 4) | (*x - 'A' + 10);
  164. break;
  165. default:
  166. return n;
  167. }
  168. x++;
  169. }
  170. return n;
  171. }
  172. static unsigned hex2unsigned(const char *x)
  173. {
  174. return (unsigned)hex2uint64(x);
  175. }
  176. extern BOOT_ARGUMENT *g_boot_arg;
  177. void* special_heap_alloc(int length)
  178. {
  179. void* buf = (void*)(u32)mblock_reserve_ext(&g_boot_arg->mblock_info,
  180. length, 0x10000, 0x80000000, 0, "fastboot_heap");
  181. return buf;
  182. }
  183. static void init_display_xy()
  184. {
  185. #if defined(DISPLAY_INFO_ON_LCM)
  186. video_clean_screen();
  187. video_set_cursor(video_get_rows()/2, 0);
  188. //video_set_cursor(1, 0);
  189. #endif
  190. }
  191. static void display_info(const char* msg)
  192. {
  193. #if defined(DISPLAY_INFO_ON_LCM)
  194. if (msg == 0) {
  195. return;
  196. }
  197. video_printf("%s\n", msg);
  198. #endif
  199. }
  200. void display_progress(const char* msg_prefix, unsigned size, unsigned totle_size)
  201. {
  202. #if defined(DISPLAY_INFO_ON_LCM)
  203. unsigned vel = 0;
  204. u64 prog = 0;
  205. unsigned time = TIME_ELAPSE;
  206. if (msg_prefix == 0) {
  207. msg_prefix = "Unknown";
  208. }
  209. if (time != 0) {
  210. vel = (unsigned)(size / time); //approximate 1024/1000
  211. vel /= 1000;
  212. time /= 1000;
  213. }
  214. if (totle_size != 0) {
  215. prog = (u64)size*100/totle_size;
  216. }
  217. video_printf("%s > %3d%% Time:%4d s Vel:%3d MB/s ", msg_prefix, (unsigned)prog, time, vel);
  218. #endif
  219. }
  220. static void display_speed_info(const char* msg_prefix, unsigned size)
  221. {
  222. #if defined(DISPLAY_INFO_ON_LCM)
  223. unsigned vel = 0;
  224. unsigned time = TIME_ELAPSE;
  225. if (msg_prefix == 0) {
  226. msg_prefix = "Unknown";
  227. }
  228. if (time != 0) {
  229. vel = (unsigned)(size / time); //approximate 1024/1000
  230. vel /= 1000;
  231. time /= 1000;
  232. }
  233. video_printf("\n%s Time:%d s Vel:%d MB/s \n", msg_prefix, time, vel);
  234. #endif
  235. }
  236. static void fastboot_fail_wrapper(const char* msg)
  237. {
  238. display_info(msg);
  239. fastboot_fail(msg);
  240. }
  241. static void fastboot_ok_wrapper(const char* msg, unsigned data_size)
  242. {
  243. display_speed_info(msg, data_size);
  244. fastboot_okay("");
  245. }
  246. void cmd_install_sig(const char *arg, void *data, unsigned sz)
  247. {
  248. fastboot_fail_wrapper("Signature command not supported");
  249. }
  250. static char error_msg[512];
  251. void set_response_msg(const char* s)
  252. {
  253. strncpy(error_msg, s, 511);
  254. }
  255. bool power_check()
  256. {
  257. //3500 mV. shut down threshold 3.45V
  258. if (get_bat_sense_volt(5) < 3500) {
  259. return false;
  260. } else {
  261. return true;
  262. }
  263. }
  264. #ifdef MTK_ULTRA_FLASH
  265. bool g_ultra_flash_enable = true;
  266. char partition_name_history[MAX_PARTITION_NAME_LEN]={0};
  267. int partition_name_history_len = 0;
  268. void switch_max_download_len(bool ultra_en);
  269. bool is_special_partition(const char* partition);
  270. bool cmd_download_ultra(const char *arg, void *data, unsigned sz);
  271. bool cmd_download_standard(const char *arg, void *data, unsigned sz);
  272. #endif
  273. void cmd_download(const char *arg, void *data, unsigned sz)
  274. {
  275. bool result = false;
  276. #ifdef MTK_ULTRA_FLASH
  277. if(g_ultra_flash_enable && (partition_name_history_len!=0) && (!is_special_partition(partition_name_history)))
  278. {
  279. result = cmd_download_ultra(arg, data, sz);
  280. }
  281. else
  282. {
  283. result = cmd_download_standard(arg, data, sz);
  284. }
  285. if(!result)
  286. {
  287. //restore the default max download size.
  288. switch_max_download_len(false);
  289. }
  290. #else
  291. cmd_download_standard(arg, data, sz);
  292. #endif
  293. return;
  294. }
  295. bool cmd_download_standard(const char *arg, void *data, unsigned sz)
  296. {
  297. char response[MAX_RSP_SIZE];
  298. unsigned len = hex2unsigned(arg);
  299. int r;
  300. if (!power_check()) {
  301. fastboot_fail("low power, need battery charging.");
  302. return false;
  303. }
  304. init_display_xy();
  305. download_size = 0;
  306. if (len > download_max) {
  307. fastboot_fail_wrapper("data is too large");
  308. return false;
  309. }
  310. snprintf(response, MAX_RSP_SIZE, "DATA%08x", len);
  311. if (usb_write(response, strlen(response)) < 0) {
  312. return false;
  313. }
  314. display_info("USB Transferring... ");
  315. TIME_START;
  316. r = usb_read(download_base, len);
  317. if ((r < 0) || ((unsigned) r != len)) {
  318. fastboot_fail_wrapper("Read USB error");
  319. fastboot_state = STATE_ERROR;
  320. return false;
  321. }
  322. download_size = len;
  323. fastboot_ok_wrapper("USB Transmission OK", len);
  324. return true;
  325. }
  326. #ifdef NAND_TYPE
  327. int get_nand_image_type(const char* arg)
  328. {
  329. int img_type = 0;
  330. if (!strncmp(arg, "system", strlen("system")) ||
  331. !strcmp(arg, "userdata") ||
  332. !strcmp(arg, "fat") ) {
  333. #if defined(MTK_NAND_UBIFS_SUPPORT) || defined(MTK_NAND_MTK_FTL_SUPPORT)
  334. img_type = UBIFS_IMG;
  335. #else
  336. img_type = YFFS2_IMG;
  337. #endif
  338. } else {
  339. img_type = RAW_DATA_IMG;
  340. }
  341. return img_type;
  342. }
  343. #endif
  344. extern part_dev_t *mt_part_get_device(void);
  345. bool cmd_flash_mmc_img(const char* arg, void* data, unsigned sz)
  346. {
  347. unsigned long long ptn = 0;
  348. unsigned long long size = 0;
  349. part_dev_t *dev;
  350. int index = INVALID_PTN;
  351. #if (defined(MTK_UFS_SUPPORT) || defined(MTK_NEW_COMBO_EMMC_SUPPORT))
  352. unsigned int part_id;
  353. #endif
  354. #ifdef MTK_SPI_NOR_SUPPORT
  355. if (!strcmp(arg, "NOR")) {
  356. ptn = 0;
  357. part_id = 0; /* If need, example : NOR_PART_BOOT1 */
  358. goto write_nor_part;
  359. } else
  360. #endif
  361. #ifdef FASTBOOT_WHOLE_FLASH_SUPPORT
  362. if (!strcmp(arg, "boot0")) {
  363. ptn = 0;
  364. part_id = EMMC_PART_BOOT1;
  365. mmc_emmc_boot_prepare();
  366. goto write_part;
  367. } else if (!strcmp(arg,"boot1")) {
  368. ptn = 0;
  369. part_id = EMMC_PART_BOOT2;
  370. goto write_part;
  371. } else if (!strcmp(arg, "partition")) {
  372. ptn = 0;
  373. part_id = EMMC_PART_USER;
  374. goto write_part;
  375. }
  376. #else
  377. if (!strcmp(arg, "partition")) {
  378. dprintf(ALWAYS, "Attempt to write partition image.\n");
  379. set_response_msg("Do not support this operation.");
  380. return false;
  381. }
  382. #endif
  383. else {
  384. index = partition_get_index(arg);
  385. if (index == INVALID_PTN) {
  386. set_response_msg("This partition doesn't exist");
  387. return false;
  388. }
  389. ptn = partition_get_offset(index);
  390. if (ptn == (unsigned long long)(-1)) {
  391. set_response_msg("partition table doesn't exist");
  392. return false;
  393. }
  394. #if (defined(MTK_UFS_SUPPORT) || defined(MTK_NEW_COMBO_EMMC_SUPPORT))
  395. part_id = partition_get_region(index);
  396. #endif
  397. if (!strcmp(arg, "boot") || !strcmp(arg, "boot_a") ||
  398. !strcmp(arg, "boot_b") || !strcmp(arg, "recovery")) {
  399. if (memcmp((void *)data, BOOTIMG_MAGIC, BOOTIMG_MAGIC_SZ-1)) {
  400. set_response_msg("image is not a boot image");
  401. return false;
  402. }
  403. }
  404. if (!strncmp(arg, "preloader", strlen("preloader"))) {
  405. dev = mt_part_get_device();
  406. #if (defined(MTK_EMMC_SUPPORT) || defined(MTK_UFS_SUPPORT))
  407. if (dev->blkdev->type == BOOTDEV_SDMMC) {
  408. int boot_wp = mmc_get_card(0)->raw_ext_csd[EXT_CSD_BOOT_WP];
  409. if (boot_wp & EXT_CSD_BOOT_WP_EN_PERM_WP) {
  410. set_response_msg("flash preloader is not permitted.");
  411. return false;
  412. }
  413. }
  414. #endif
  415. #ifdef PLATFORM_FASTBOOT_EMPTY_STORAGE
  416. if (process_preloader(data, &sz)) {
  417. set_response_msg("not a valid preloader.");
  418. return false;
  419. }
  420. ptn = 0;
  421. #else
  422. if (is_preloader_bin_format(data)) {
  423. //preloader_xxx.bin
  424. if (dev->blkdev->type == BOOTDEV_SDMMC)
  425. ptn = HEADER_BLOCK_SIZE_EMMC;
  426. else if (dev->blkdev->type == BOOTDEV_UFS)
  427. ptn = HEADER_BLOCK_SIZE_UFS;
  428. else
  429. ptn = HEADER_BLOCK_SIZE_NAND;
  430. }
  431. else //migh be preloader.img. offset = 0
  432. ptn = 0;
  433. #endif
  434. }
  435. size = partition_get_size(index);
  436. if (ROUND_TO_PAGE(sz,511) > size) {
  437. set_response_msg("size too large");
  438. return false;
  439. }
  440. }
  441. #ifdef FASTBOOT_WHOLE_FLASH_SUPPORT
  442. write_part:
  443. #endif // FASTBOOT_WHOLE_FLASH_SUPPORT
  444. #ifdef EMMC_TYPE
  445. #if (defined(MTK_UFS_SUPPORT) || defined(MTK_NEW_COMBO_EMMC_SUPPORT))
  446. dprintf (ALWAYS, "partid %d, addr 0x%llx, size 0x%x\n", part_id, ptn, sz);
  447. if (emmc_write(part_id, ptn , (unsigned int *)data, sz) != sz)
  448. #else
  449. if (emmc_write(ptn , (unsigned int *)data, sz) != sz)
  450. #endif
  451. #endif
  452. #ifdef NAND_TYPE
  453. #if defined(MTK_MLC_NAND_SUPPORT) || defined(MTK_TLC_NAND_SUPPORT)
  454. if (nand_write_img((u64)ptn, (char*)data, sz,(u64)size,get_nand_image_type(arg)))
  455. #else
  456. if (nand_write_img((u32)ptn, (char*)data, sz,(u32)size,get_nand_image_type(arg)))
  457. #endif
  458. #endif
  459. {
  460. set_response_msg("flash write failure");
  461. return false;
  462. }
  463. #ifdef FASTBOOT_WHOLE_FLASH_SUPPORT
  464. if (!strcmp(arg, "partition")) {
  465. mt_part_init(0);
  466. }
  467. #endif
  468. //fastboot_okay("");
  469. return true;
  470. #ifdef NOR_TYPE
  471. #ifdef MTK_SPI_NOR_SUPPORT
  472. write_nor_part:
  473. dprintf (ALWAYS, "partid %d, addr 0x%llx, size 0x%x\n", part_id, ptn, sz);
  474. if (nor_write_part(part_id, ptn , (unsigned int *)data, (u64)sz) != sz) {
  475. set_response_msg("SPI NOR flash write failure");
  476. return false;
  477. }
  478. //fastboot_okay("");
  479. return false;
  480. #endif
  481. #endif
  482. }
  483. bool cmd_flash_mmc_sparse_img(const char* arg, void* data, unsigned sz)
  484. {
  485. unsigned int chunk;
  486. unsigned int chunk_data_sz;
  487. static uint32_t *fill_buf = NULL;
  488. uint32_t fill_val;
  489. uint32_t chunk_blk_cnt = 0;
  490. uint32_t i;
  491. unsigned long long size_wrote = 0;
  492. sparse_header_t *sparse_header;
  493. chunk_header_t *chunk_header;
  494. uint32_t total_blocks = 0;
  495. unsigned long long ptn = 0;
  496. unsigned long long size = 0;
  497. int index = INVALID_PTN;
  498. #if (defined(MTK_UFS_SUPPORT) || defined(MTK_NEW_COMBO_EMMC_SUPPORT))
  499. unsigned int part_id;
  500. #endif
  501. index = partition_get_index(arg);
  502. if (INVALID_PTN == index) {
  503. set_response_msg("This partition doesn't exist");
  504. return false;
  505. }
  506. ptn = partition_get_offset(index);
  507. if (ptn == (unsigned long long)(-1)) {
  508. set_response_msg("partition offset is wrong");
  509. return false;
  510. }
  511. dprintf(ALWAYS, "partition(%s) index is %d, ptn is 0x%llx\n", arg, index, ptn);
  512. #if (defined(MTK_UFS_SUPPORT) || defined(MTK_NEW_COMBO_EMMC_SUPPORT))
  513. part_id = partition_get_region(index);
  514. #endif
  515. size = partition_get_size(index);
  516. /* Read and skip over sparse image header */
  517. sparse_header = (sparse_header_t *) data;
  518. dprintf(ALWAYS, "Image size span 0x%llx, partition size 0x%llx\n", (unsigned long long)sparse_header->total_blks*sparse_header->blk_sz, size);
  519. if ((unsigned long long)sparse_header->total_blks*sparse_header->blk_sz > size) {
  520. set_response_msg("sparse image size span overflow.");
  521. return false;
  522. }
  523. if(sparse_header->file_hdr_sz > sz)
  524. {
  525. set_response_msg("sparse image header invalid.");
  526. return false;
  527. }
  528. data += sizeof(sparse_header_t);
  529. if (sparse_header->file_hdr_sz > sizeof(sparse_header_t)) {
  530. /* Skip the remaining bytes in a header that is longer than
  531. * we expected.
  532. */
  533. data += (sparse_header->file_hdr_sz - sizeof(sparse_header_t));
  534. }
  535. dprintf (ALWAYS, "=== Sparse Image Header ===\n");
  536. dprintf (ALWAYS, "magic: 0x%x\n", sparse_header->magic);
  537. dprintf (ALWAYS, "major_version: 0x%x\n", sparse_header->major_version);
  538. dprintf (ALWAYS, "minor_version: 0x%x\n", sparse_header->minor_version);
  539. dprintf (ALWAYS, "file_hdr_sz: %d\n", sparse_header->file_hdr_sz);
  540. dprintf (ALWAYS, "chunk_hdr_sz: %d\n", sparse_header->chunk_hdr_sz);
  541. dprintf (ALWAYS, "blk_sz: %d\n", sparse_header->blk_sz);
  542. dprintf (ALWAYS, "total_blks: %d\n", sparse_header->total_blks);
  543. dprintf (ALWAYS, "total_chunks: %d\n", sparse_header->total_chunks);
  544. display_info("\nWriting Flash ... ");
  545. /* Start processing chunks */
  546. for (chunk=0; chunk<sparse_header->total_chunks; chunk++) {
  547. /* Read and skip over chunk header */
  548. chunk_header = (chunk_header_t *)data;
  549. data += sizeof(chunk_header_t);
  550. //dprintf (ALWAYS, "=== Chunk Header ===\n");
  551. //dprintf (ALWAYS, "chunk_type: 0x%x\n", chunk_header->chunk_type);
  552. //dprintf (ALWAYS, "chunk_data_sz: 0x%x\n", chunk_header->chunk_sz);
  553. //dprintf (ALWAYS, "total_size: 0x%x\n", chunk_header->total_sz);
  554. if (sparse_header->chunk_hdr_sz > sizeof(chunk_header_t)) {
  555. /* Skip the remaining bytes in a header that is longer than
  556. * we expected.
  557. */
  558. data += (sparse_header->chunk_hdr_sz - sizeof(chunk_header_t));
  559. }
  560. if(size/sparse_header->blk_sz < chunk_header->chunk_sz)
  561. {
  562. set_response_msg("sparse chunk size is too big.");
  563. return false;
  564. }
  565. chunk_data_sz = sparse_header->blk_sz * chunk_header->chunk_sz;
  566. //check chunk bounadary
  567. if(sparse_header->blk_sz * ((unsigned long long)chunk_header->chunk_sz + total_blocks) > size)
  568. {
  569. set_response_msg("sparse chunk size overflow.");
  570. return false;
  571. }
  572. if((sparse_header->total_blks - total_blocks) < chunk_header->chunk_sz)
  573. {
  574. set_response_msg("sparse chunk blocks bigger than total blocks.");
  575. return false;
  576. }
  577. switch (chunk_header->chunk_type) {
  578. case CHUNK_TYPE_RAW:
  579. {
  580. if (chunk_header->total_sz != (sparse_header->chunk_hdr_sz +
  581. chunk_data_sz)) {
  582. set_response_msg("Bogus chunk size for chunk type Raw");
  583. return false;
  584. }
  585. dprintf (ALWAYS, "Raw: start block addr: 0x%x\n", total_blocks);
  586. #ifdef EMMC_TYPE
  587. #if (defined(MTK_UFS_SUPPORT) || defined(MTK_NEW_COMBO_EMMC_SUPPORT))
  588. //dprintf (ALWAYS, "partid %d, addr 0x%llx, partsz 0x%x\n", part_id, ptn + ((unsigned long long)total_blocks*sparse_header->blk_sz) , chunk_data_sz);
  589. if (emmc_write(part_id, ptn + ((unsigned long long)total_blocks*sparse_header->blk_sz) , data, chunk_data_sz) != chunk_data_sz)
  590. #else
  591. if (emmc_write(ptn + ((unsigned long long)total_blocks*sparse_header->blk_sz) , data, chunk_data_sz) != chunk_data_sz)
  592. #endif
  593. #endif
  594. #ifdef NAND_TYPE
  595. #if defined(MTK_MLC_NAND_SUPPORT) || defined(MTK_TLC_NAND_SUPPORT)
  596. if (nand_write_img((u64)(ptn + ((unsigned long long)total_blocks*sparse_header->blk_sz)), (char*)data, chunk_data_sz,(u64)size,get_nand_image_type(arg)))
  597. #else
  598. if (nand_write_img((u32)(ptn + ((unsigned long long)total_blocks*sparse_header->blk_sz)), (char*)data, chunk_data_sz,(u32)size,get_nand_image_type(arg)))
  599. #endif
  600. #endif
  601. {
  602. set_response_msg("flash write failure");
  603. return false;
  604. }
  605. total_blocks += chunk_header->chunk_sz;
  606. data += chunk_data_sz;
  607. break;
  608. }
  609. case CHUNK_TYPE_DONT_CARE:
  610. {
  611. dprintf (ALWAYS, "!!Blank: start: 0x%x offset: 0x%x\n", total_blocks, chunk_header->chunk_sz);
  612. total_blocks += chunk_header->chunk_sz;
  613. break;
  614. }
  615. case CHUNK_TYPE_FILL:
  616. {
  617. dprintf (ALWAYS, "%s %d: CHUNK_TYPE_FILL=0x%x size=%d chunk_data_sz=%d\n", __FUNCTION__, __LINE__, *(uint32_t *)data, ROUNDUP(sparse_header->blk_sz, CACHE_LINE), chunk_data_sz);
  618. if (chunk_header->total_sz != (sparse_header->chunk_hdr_sz + sizeof(uint32_t))) {
  619. set_response_msg("Bogus chunk size for chunk type FILL");
  620. return false;
  621. }
  622. #define FILL_BUF_BLOCK_CNT ((4*1024*1024)/sparse_header->blk_sz)
  623. #define FILL_BUF_LEN (FILL_BUF_BLOCK_CNT * sparse_header->blk_sz)
  624. //fill_buf = (uint32_t *)memalign(CACHE_LINE, FILL_BUF_LEN);
  625. if(fill_buf == NULL)
  626. {
  627. fill_buf = special_heap_alloc(FILL_BUF_LEN);
  628. }
  629. if (!fill_buf) {
  630. set_response_msg("Malloc failed for: CHUNK_TYPE_FILL");
  631. return false;
  632. }
  633. fill_val = *(uint32_t *)data;
  634. data = (char *) data + sizeof(uint32_t);
  635. chunk_blk_cnt = chunk_data_sz / sparse_header->blk_sz;
  636. unsigned int int_cnt = FILL_BUF_LEN / sizeof(fill_val);
  637. for (i = 0; i < int_cnt; i++) {
  638. fill_buf[i] = fill_val;
  639. }
  640. unsigned int left = chunk_blk_cnt;
  641. while (left > 0) {
  642. unsigned int todo = (left > FILL_BUF_BLOCK_CNT) ? FILL_BUF_BLOCK_CNT : left;
  643. #if (defined(MTK_UFS_SUPPORT) || defined(MTK_NEW_COMBO_EMMC_SUPPORT))
  644. size_wrote = emmc_write(part_id, ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
  645. fill_buf, (u64)todo * sparse_header->blk_sz);
  646. #else
  647. size_wrote = emmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
  648. fill_buf, (u64)todo * sparse_header->blk_sz);
  649. #endif
  650. if (size_wrote != (unsigned long long)todo * sparse_header->blk_sz) {
  651. set_response_msg("CHUNK_TYPE_FILL flash write failure");
  652. //free(fill_buf);
  653. return false;
  654. }
  655. total_blocks += todo;
  656. left -= todo;
  657. }
  658. //free(fill_buf);
  659. break;
  660. }
  661. case CHUNK_TYPE_CRC:
  662. {
  663. if (chunk_header->total_sz != sparse_header->chunk_hdr_sz) {
  664. set_response_msg("Bogus chunk size for chunk type Dont Care");
  665. return false;
  666. }
  667. total_blocks += chunk_header->chunk_sz;
  668. data += chunk_data_sz;
  669. break;
  670. }
  671. default:
  672. set_response_msg("Unknown chunk type");
  673. return false;
  674. }
  675. display_progress("\rWrite Data", total_blocks*sparse_header->blk_sz, sparse_header->total_blks*sparse_header->blk_sz);
  676. }
  677. dprintf(ALWAYS, "Wrote %d blocks, expected to write %d blocks\n",
  678. total_blocks, sparse_header->total_blks);
  679. if (total_blocks != sparse_header->total_blks) {
  680. set_response_msg("sparse image write failure");
  681. return false;
  682. } else {
  683. display_info("\n\nOK");
  684. fastboot_okay("");
  685. }
  686. return true;
  687. }
  688. extern int mboot_recovery_load_raw_part_offset(char *part_name, unsigned long *addr, unsigned long offset, unsigned int size) __attribute__((weak));
  689. int _virtual_partition_support(const char *arg, void *data, unsigned int* p_sz)
  690. {
  691. #define TMP_DOWNLOAD_SIZE 52*1024*1024 //52MB, because kernel size(64M) - pagetable max size (8M) - ramdisk size(Estimate 4M)
  692. unsigned t_bootimg_addr = ((u32)data);
  693. void* new_data =(void *)((u32)data + SCRATCH_SIZE - TMP_DOWNLOAD_SIZE);
  694. bool _is_zimage = false;
  695. struct bootimg_hdr *p_boot_hdr;
  696. unsigned int t_kernel_addr;
  697. unsigned int t_ramdisk_addr;
  698. unsigned int sz = *p_sz;
  699. char* tmp = (void *)arg;
  700. int ret;
  701. if (!memcmp(arg, "zimage", strlen("zimage"))) {
  702. _is_zimage = true;
  703. dprintf(INFO,"Get zimage\n");
  704. } else if (!memcmp(arg, "ramdisk", strlen("ramdisk"))) {
  705. dprintf(INFO,"Get ramdisk\n");
  706. } else {
  707. return 0;
  708. }
  709. /* check size first */
  710. if (sz > TMP_DOWNLOAD_SIZE)
  711. return -ENOMEM;
  712. /* copy ori data to temp addr */
  713. memcpy(new_data, data, sz);
  714. /* copy bootimg header content */
  715. //clean space for img_hdr make the debug easier, 8k is enough for most case (page size < 8k)
  716. memset(data, 0, 0x2000);
  717. #ifdef MTK_GPT_SCHEME_SUPPORT
  718. ret = mboot_recovery_load_raw_part_offset("boot", (void *)t_bootimg_addr, 0, sizeof(struct bootimg_hdr));
  719. #else
  720. ret = mboot_recovery_load_raw_part_offset(PART_BOOTIMG, (void *)t_bootimg_addr, 0, sizeof(struct bootimg_hdr));
  721. #endif
  722. if (ret < 0) {
  723. return ret;
  724. }
  725. p_boot_hdr = (void *)t_bootimg_addr;
  726. dprintf(INFO,"ori kernel_sz: %x\n", p_boot_hdr->kernel_sz);
  727. dprintf(INFO,"ori ramdisk_sz: %x\n", p_boot_hdr->ramdisk_sz);
  728. t_kernel_addr = t_bootimg_addr + p_boot_hdr->page_sz;
  729. if (_is_zimage == true) {
  730. /* copy kernel content from new_data*/
  731. memcpy((void *)t_kernel_addr, new_data, sz);
  732. /* copy ramdisk content from flash */
  733. t_ramdisk_addr = ROUNDUP(t_kernel_addr + sz, p_boot_hdr->page_sz);
  734. #ifdef MTK_GPT_SCHEME_SUPPORT
  735. ret = mboot_recovery_load_raw_part_offset("boot", (void *)t_ramdisk_addr,
  736. ROUNDUP(p_boot_hdr->kernel_sz + p_boot_hdr->page_sz, p_boot_hdr->page_sz), p_boot_hdr->ramdisk_sz);
  737. #else
  738. ret = mboot_recovery_load_raw_part_offset(PART_BOOTIMG, (void *)t_ramdisk_addr,
  739. ROUNDUP(p_boot_hdr->kernel_sz + p_boot_hdr->page_sz, p_boot_hdr->page_sz), p_boot_hdr->ramdisk_sz);
  740. #endif
  741. if (ret < 0) {
  742. return ret;
  743. }
  744. /* update header */
  745. p_boot_hdr->kernel_sz = sz;
  746. dprintf(INFO,"->kernel_sz %x\n", sz);
  747. } else {
  748. /* copy kernel content from flash*/
  749. #ifdef MTK_GPT_SCHEME_SUPPORT
  750. ret = mboot_recovery_load_raw_part_offset("boot", (void *)t_kernel_addr, p_boot_hdr->page_sz, p_boot_hdr->kernel_sz);
  751. #else
  752. ret = mboot_recovery_load_raw_part_offset(PART_BOOTIMG, (void *)t_kernel_addr, p_boot_hdr->page_sz, p_boot_hdr->kernel_sz);
  753. #endif
  754. if (ret < 0) {
  755. return ret;
  756. }
  757. t_ramdisk_addr = ROUNDUP(t_kernel_addr + p_boot_hdr->kernel_sz, p_boot_hdr->page_sz);
  758. /* copy ramdisk content from new_data*/
  759. memcpy((void *)t_ramdisk_addr, new_data, sz);
  760. /* update header */
  761. p_boot_hdr->ramdisk_sz = sz;
  762. dprintf(INFO,"->ramdisk_sz %x\n", sz);
  763. }
  764. /* overwrite arg*/
  765. *p_sz = p_boot_hdr->page_sz + ROUNDUP(p_boot_hdr->kernel_sz, p_boot_hdr->page_sz)+ ROUNDUP(p_boot_hdr->ramdisk_sz, p_boot_hdr->page_sz);
  766. /*
  767. * FIXME or LIMITATION:
  768. * tmp is an argument passed all the way from the handle() function. The handle() function
  769. * is a legacy of the official little kernel release. If the length of the destination
  770. * buffer "tmp" is needed, the function prototype of handle() needs to have one more
  771. * argument. In other words, all the functions registered in fastboot need to be altered.
  772. */
  773. /* 4 for the string, "boot", 1 for terminater, '\0'*/
  774. if (strlen(tmp) >= 5) /*tmp was 'ramdisk' or 'zimage'. Add check to avoid "Out-of-bound access" coverity scan.*/
  775. strncpy(tmp, "boot", 4 + 1);
  776. return 0;
  777. }
  778. /******************************************************************************
  779. * The mkimage tool will round up the image size to 16-byte alignment boundary
  780. * by padding zero to the tail of the image before a 512-byte mkimage header is
  781. * "pre-pended" to it. The dsize field in the mkimage header is the real size
  782. * of the image content before padding is applied, and it does not include the
  783. * size of the header.
  784. *
  785. * The preloader image does not have a mkimage header by default. To make the
  786. * flow consistent, a mkimage header is "pre-pended" to the preloader before it
  787. * is concatenated to the "single boot loader". Please note that the header
  788. * along with the image content of an image (except for the preloader image)
  789. * needs to be flashed to the storage. In other words, do not flash the mkimage
  790. * header of the preloader to the storage. It is fine to flash the padding bytes
  791. * to the storage.
  792. ******************************************************************************/
  793. bool cmd_flash_mmc_standard(const char *arg, void *data, unsigned sz);
  794. void cmd_flash_mmc(const char *arg, void *data, unsigned sz)
  795. {
  796. #ifdef MTK_ULTRA_FLASH
  797. bool result = false;
  798. if(g_ultra_flash_enable && (partition_name_history_len!=0) && (!is_special_partition(partition_name_history)))
  799. {
  800. fastboot_info(partition_name_history);
  801. fastboot_okay("");
  802. result = true;
  803. }
  804. else
  805. {
  806. result = flash_storage(arg, data, sz);
  807. }
  808. if(!result)
  809. {
  810. //restore the default max download size.
  811. switch_max_download_len(false);
  812. }
  813. #else
  814. flash_storage(arg, data, sz);
  815. #endif
  816. return;
  817. }
  818. #define UNI_BOOTLOADER_MAGIC 0xEF77FD33
  819. #define MAX_BOOTLOADER_IMAGE 16
  820. struct partition_cell
  821. {
  822. char name[32];
  823. unsigned int size;
  824. };
  825. struct uni_bootloader_hdr
  826. {
  827. unsigned int magic; //0xEF77FD33
  828. unsigned int version; //1
  829. unsigned int header_size; // total header's size
  830. unsigned int image_cnt; //images count
  831. struct partition_cell part_list[MAX_BOOTLOADER_IMAGE];
  832. };
  833. bool flash_storage(const char* arg, void* data, unsigned sz)
  834. {
  835. bool result = false;
  836. if (strcmp(arg, "singlebootloader") != 0 && strcmp(arg, "bootloader") != 0)
  837. {
  838. result = cmd_flash_mmc_standard(arg, data, sz);
  839. if (result)
  840. {
  841. fastboot_okay("");
  842. }
  843. else
  844. {
  845. fastboot_fail(error_msg);
  846. }
  847. return result;
  848. }
  849. dprintf(ALWAYS, "@download singlebootloader.\n");
  850. dprintf(ALWAYS, "@size 0x%x.\n", sz);
  851. struct uni_bootloader_hdr* hdr = data;
  852. if(hdr->magic != UNI_BOOTLOADER_MAGIC
  853. || hdr->image_cnt > MAX_BOOTLOADER_IMAGE
  854. || hdr->header_size != sizeof(struct uni_bootloader_hdr))
  855. {
  856. fastboot_fail("NOT UNI_BOOTLOADER_MAGIC OR COUNT OVERFLOW.");
  857. return false;
  858. }
  859. void* img_data = data + hdr->header_size;
  860. int idx = 0;
  861. for (;idx < hdr->image_cnt; ++idx)
  862. {
  863. dprintf(ALWAYS, "@split download %s.\n", hdr->part_list[idx].name);
  864. bool result = cmd_flash_mmc_standard(hdr->part_list[idx].name, img_data,
  865. hdr->part_list[idx].size);
  866. if (!result)
  867. {
  868. fastboot_fail(error_msg);
  869. return false;
  870. }
  871. img_data += hdr->part_list[idx].size;
  872. }
  873. fastboot_okay("");
  874. return result;
  875. }
  876. bool cmd_flash_mmc_standard(const char *arg, void *data, unsigned sz)
  877. {
  878. bool result = false;
  879. #ifdef MTK_SECURITY_SW_SUPPORT
  880. unsigned int permitted = 0;
  881. char msg[64];
  882. #endif
  883. #ifdef MTK_GPT_SCHEME_SUPPORT
  884. #if defined(PLATFORM_FASTBOOT_EMPTY_STORAGE) || defined(MTK_GPT_UPDATE_SUPPORT)
  885. int err;
  886. #endif
  887. #endif
  888. union mkimg_hdr *part_hdr;
  889. bool single_boot_loader = false;
  890. bool flash_tee2 = false; // If ATF was found, flash both tee1 and tee2.
  891. if (sz == 0) {
  892. //fastboot_okay("");
  893. return true;
  894. }
  895. if (!strcmp(arg, "singlebootloader"))
  896. single_boot_loader = true;
  897. u32 remaining_len = sz;
  898. u32 counter = 5;
  899. while (remaining_len && (counter > 0)) {
  900. part_hdr = (union mkimg_hdr *)data;
  901. if (single_boot_loader) {
  902. if (flash_tee2) {
  903. arg = "tee2";
  904. flash_tee2 = false;
  905. } else {
  906. arg = part_hdr->info.name;
  907. if ((!strncmp(arg, "lk", 3)) || (!strncmp(arg, "LK", 3))) {
  908. arg = "lk";
  909. sz = sizeof(union mkimg_hdr);
  910. }
  911. else if ((!strncmp(arg, "logo", 5)) || (!strncmp(arg, "LOGO", 5))) {
  912. arg = "logo";
  913. sz = sizeof(union mkimg_hdr);
  914. }
  915. else if ((!strncmp(arg, "atf", 4)) || (!strncmp(arg, "ATF", 4))) {
  916. arg = "tee1";
  917. sz = sizeof(union mkimg_hdr);
  918. flash_tee2 = true;
  919. }
  920. else if ((!strncmp(arg, "preloader", 10)) || (!strncmp(arg, "PRELOADER", 10))) {
  921. arg = "preloader";
  922. sz = 0;
  923. data += sizeof(union mkimg_hdr);
  924. if (remaining_len < sizeof(union mkimg_hdr)) {
  925. set_response_msg("not enough remaining length");
  926. return false;
  927. }
  928. remaining_len -= sizeof(union mkimg_hdr);
  929. }
  930. else {
  931. set_response_msg("unknown data");
  932. return false;
  933. }
  934. sz += ROUNDUP(part_hdr->info.dsz, 16);
  935. if (remaining_len < sz) {
  936. set_response_msg("not enough remaining length");
  937. return false;
  938. }
  939. }
  940. }
  941. // security check here.
  942. // ret = decrypt_scm((uint32 **) &data, &sz);
  943. #ifdef MTK_SECURITY_SW_SUPPORT
  944. if (sec_dl_permission_chk(arg, &permitted)) {
  945. snprintf(msg, sizeof(msg), "failed to get download permission for partition '%s'\n", arg);
  946. set_response_msg(msg);
  947. return false;
  948. }
  949. if (0 == permitted) {
  950. snprintf(msg, sizeof(msg), "download for partition '%s' is not allowed\n", arg);
  951. set_response_msg(msg);
  952. return false;
  953. }
  954. #endif
  955. #ifdef MTK_GPT_SCHEME_SUPPORT
  956. #if defined(PLATFORM_FASTBOOT_EMPTY_STORAGE) || defined(MTK_GPT_UPDATE_SUPPORT)
  957. if (!strcmp(arg, "gpt")) { //if arg == "gpt" , update pmbr, pgpt, and sgpt. Then re-init partition table for fastboot.
  958. err = gpt_partition_table_update(arg, data, sz);
  959. if (err) {
  960. set_response_msg("failed to update gpt partition");
  961. return false;
  962. }
  963. read_gpt(partition); //re-init partition table afster update pmbor, pgpt and sgpt
  964. //fastboot_okay("");
  965. return true;
  966. }
  967. #endif
  968. #endif
  969. TIME_START;
  970. if (_virtual_partition_support(arg, data, &sz) < 0) {
  971. set_response_msg("virtual partition write fail");
  972. return false;
  973. }
  974. sparse_header_t *sparse_header = (sparse_header_t *) data;
  975. if (sparse_header->magic != SPARSE_HEADER_MAGIC)
  976. result = cmd_flash_mmc_img(arg, data, sz);
  977. else
  978. #ifdef NAND_TYPE
  979. #ifdef MNTL_SUPPORT
  980. {
  981. if (is_mntl_partition(arg))
  982. {
  983. dprintf(CRITICAL, "%s: mntl partition %s\n",
  984. __FUNCTION__, arg);
  985. result = mntl_flash_img(arg, data, sz);
  986. if (!result)
  987. {
  988. set_response_msg("mntl flash image err.");
  989. return false;
  990. }
  991. }
  992. else
  993. {
  994. result = cmd_flash_nand_sparse_img(arg, data, sz);
  995. }
  996. }
  997. #else
  998. {
  999. result = cmd_flash_nand_sparse_img(arg, data, sz);
  1000. }
  1001. #endif
  1002. #endif
  1003. #ifdef EMMC_TYPE
  1004. {
  1005. result = cmd_flash_mmc_sparse_img(arg, data, sz);
  1006. }
  1007. #endif
  1008. if(!result)
  1009. {
  1010. return result;
  1011. }
  1012. if (flash_tee2) {
  1013. counter--;
  1014. continue; // Preserve "data" and "sz" for reuse.
  1015. }
  1016. remaining_len -= sz;
  1017. data += sz;
  1018. counter--;
  1019. }
  1020. return result;
  1021. }
  1022. void cmd_erase_mmc(const char *arg, void *data, unsigned sz)
  1023. {
  1024. #if (defined(MTK_UFS_SUPPORT) || defined(MTK_NEW_COMBO_EMMC_SUPPORT))
  1025. unsigned int part_id;
  1026. #endif
  1027. unsigned long long ptn = 0;
  1028. unsigned long long size = 0;
  1029. int index = INVALID_PTN;
  1030. int erase_ret = MMC_ERR_NONE;
  1031. #ifdef MTK_SECURITY_SW_SUPPORT
  1032. unsigned int permitted = 0;
  1033. char msg[64];
  1034. #endif
  1035. dprintf (ALWAYS, "cmd_erase_mmc\n");
  1036. #ifdef MTK_SPI_NOR_SUPPORT
  1037. if (!strcmp(arg, "NOR")) {
  1038. ptn = 0;
  1039. size = nor_get_device_capacity();
  1040. part_id = 0;/* NOR_PART_BOOT1; */
  1041. goto erase_nor_part;
  1042. } else
  1043. #endif
  1044. #ifdef FASTBOOT_WHOLE_FLASH_SUPPORT
  1045. if (!strcmp(arg, "boot0")) {
  1046. ptn = 0;
  1047. size = mmc_get_region_size(EMMC_PART_BOOT1);
  1048. part_id = EMMC_PART_BOOT1;
  1049. } else if (!strcmp(arg, "boot1")) {
  1050. ptn = 0;
  1051. size = mmc_get_region_size(EMMC_PART_BOOT2);
  1052. part_id = EMMC_PART_BOOT2;
  1053. } else if (!strcmp(arg, "partition")) {
  1054. ptn = 0;
  1055. size = mmc_get_region_size(EMMC_PART_USER);
  1056. part_id = EMMC_PART_USER;
  1057. } else
  1058. #endif
  1059. {
  1060. index = partition_get_index(arg);
  1061. if (index == -1) {
  1062. fastboot_fail_wrapper("Partition table doesn't exist");
  1063. return;
  1064. }
  1065. #ifdef MTK_SECURITY_SW_SUPPORT
  1066. if (sec_format_permission_chk(arg, &permitted)) {
  1067. snprintf(msg, sizeof(msg), "failed to get format permission for partition '%s'\n", arg);
  1068. fastboot_fail(msg);
  1069. return;
  1070. }
  1071. if (0 == permitted) {
  1072. snprintf(msg, sizeof(msg), "format for partition '%s' is not allowed\n", arg);
  1073. fastboot_fail(msg);
  1074. return;
  1075. }
  1076. #endif
  1077. #if (defined(MTK_UFS_SUPPORT) || defined(MTK_NEW_COMBO_EMMC_SUPPORT))
  1078. part_id = partition_get_region(index);
  1079. #endif
  1080. ptn = partition_get_offset(index);
  1081. size = partition_get_size(index);
  1082. }
  1083. TIME_START;
  1084. #ifdef EMMC_TYPE
  1085. #if (defined(MTK_UFS_SUPPORT) || defined(MTK_NEW_COMBO_EMMC_SUPPORT))
  1086. erase_ret = emmc_erase(part_id, ptn, size);
  1087. #else
  1088. erase_ret = emmc_erase(ptn, size);
  1089. #endif
  1090. #endif
  1091. #ifdef NAND_TYPE
  1092. #ifdef MNTL_SUPPORT
  1093. if (is_mntl_partition(arg)) {
  1094. dprintf(ALWAYS, "%s: mntl partition %s\n",
  1095. __FUNCTION__, arg);
  1096. erase_ret = mntl_erase(arg, data, sz);
  1097. } else
  1098. erase_ret = nand_erase(ptn,size);
  1099. #else
  1100. erase_ret = nand_erase(ptn,size);
  1101. #endif
  1102. #endif
  1103. if (erase_ret == MMC_ERR_NONE) {
  1104. fastboot_ok_wrapper("OK", size);
  1105. } else {
  1106. fastboot_fail_wrapper("Erase error.");
  1107. }
  1108. return;
  1109. #ifdef NOR_TYPE
  1110. erase_nor_part:
  1111. dprintf (ALWAYS, "partid %d, addr 0x%llx, size 0x%llx\n", part_id, ptn, size);
  1112. erase_ret = nor_erase_part(part_id, ptn, size);
  1113. if (erase_ret == 0/* NOR_ERR_NONE */) { /* NOR_ERR_NONE suppose to be zero */
  1114. fastboot_ok_wrapper("OK", size);
  1115. } else {
  1116. fastboot_fail_wrapper("Erase SPI NOR flash error.");
  1117. }
  1118. return;
  1119. #endif
  1120. }
  1121. /****************NEW CACHE WRITE*************************/
  1122. #if defined(NAND_TYPE)
  1123. typedef struct data_cache {
  1124. unsigned char* base;
  1125. unsigned int len;
  1126. unsigned int offset;
  1127. unsigned int blocks_per_cache;
  1128. bool is_first_write;
  1129. bool valid_data;
  1130. } data_cache_t;
  1131. data_cache_t* cache;
  1132. static void memfill(unsigned int* addr, unsigned int value, unsigned int count)
  1133. {
  1134. unsigned int i = 0;
  1135. for (; i<count; ++i) {
  1136. addr[i] = value;
  1137. }
  1138. return;
  1139. }
  1140. typedef struct nand_arg {
  1141. unsigned long long ptn;
  1142. unsigned int img_type;
  1143. unsigned long long size; //partition size
  1144. } nand_arg_t;
  1145. extern int nand_get_alignment();
  1146. unsigned int get_cache_size()
  1147. {
  1148. return (unsigned int)nand_get_alignment();
  1149. }
  1150. extern int nand_img_read(unsigned long long source, unsigned char * dst, int size);
  1151. static bool cached_write_data(unsigned int* start_blocks, char* data, unsigned long long data_sz,unsigned int chunk_type, unsigned int sparse_blk_sz, void* arg)
  1152. {
  1153. unsigned long long byte_to_process = data_sz;
  1154. unsigned int byte_processed = 0;
  1155. bool skip_zero_copy = false; //only affect CHUNK_TYPE_DONT_CARE
  1156. unsigned int total_blocks = *start_blocks;
  1157. nand_arg_t* nand = (nand_arg_t*)arg;
  1158. while (byte_to_process != 0) {
  1159. unsigned int slot_len = (byte_to_process > cache->len - cache->offset) ? cache->len - cache->offset :byte_to_process;
  1160. if (chunk_type == CHUNK_TYPE_RAW ||chunk_type == CHUNK_TYPE_FILL) {
  1161. if (cache->is_first_write && (!cache->valid_data) && cache->offset!=0) {
  1162. #if defined(MTK_MLC_NAND_SUPPORT)
  1163. nand_img_read((u64)(nand->ptn + ((unsigned long long)total_blocks*sparse_blk_sz)), (char*)cache->base, cache->len);
  1164. #else
  1165. nand_img_read((u32)(nand->ptn + ((unsigned long long)total_blocks*sparse_blk_sz)), (char*)cache->base, cache->len);
  1166. #endif
  1167. dprintf(ALWAYS, "Read ptn = 0x%llx, Address 0x%x = 0x%x\n", nand->ptn, total_blocks,*(int*)cache->base);
  1168. cache->is_first_write = false;
  1169. }
  1170. }
  1171. if (chunk_type == CHUNK_TYPE_RAW) {
  1172. memcpy(cache->base+cache->offset, data+byte_processed, slot_len);
  1173. cache->valid_data = true;
  1174. } else if (chunk_type == CHUNK_TYPE_DONT_CARE ) {
  1175. if (!cache->valid_data) {
  1176. skip_zero_copy = true;
  1177. }
  1178. if (!skip_zero_copy)
  1179. memset(cache->base+cache->offset, 0xFF, slot_len);
  1180. } else if (chunk_type == CHUNK_TYPE_FILL) {
  1181. memfill((unsigned int*)(cache->base+cache->offset), *(unsigned int*)data, slot_len/sizeof(unsigned int));
  1182. cache->valid_data = true;
  1183. }
  1184. cache->offset += slot_len;
  1185. if (cache->offset == cache->len) { //cache full
  1186. dprintf(ALWAYS, "@@@@write At block(x4K) 0x%x\n", total_blocks);
  1187. if (!skip_zero_copy) {
  1188. #if defined(MTK_MLC_NAND_SUPPORT)
  1189. dprintf(ALWAYS, "Address 0x%x = 0x%x\n", total_blocks,*(int*)cache->base);
  1190. if (nand_write_img((u64)(nand->ptn + ((unsigned long long)total_blocks*sparse_blk_sz)), (char*)cache->base, cache->len,nand->size,nand->img_type))
  1191. #else
  1192. if (nand_write_img((u32)(nand->ptn + ((unsigned long long)total_blocks*sparse_blk_sz)), (char*)cache->base, cache->len,nand->size,nand->img_type))
  1193. #endif
  1194. {
  1195. dprintf(ALWAYS, "@@@@write failed\n");
  1196. return false;
  1197. }
  1198. }
  1199. cache->offset = 0; //start new package.
  1200. byte_to_process -= slot_len;
  1201. byte_processed += slot_len;
  1202. total_blocks += cache->blocks_per_cache;
  1203. cache->valid_data = false;
  1204. } else {
  1205. //can not full cache.
  1206. break;
  1207. }
  1208. if (chunk_type == CHUNK_TYPE_DONT_CARE) {
  1209. skip_zero_copy = true;
  1210. }
  1211. }
  1212. *start_blocks = total_blocks;
  1213. return true;
  1214. }
  1215. bool cmd_flash_nand_sparse_img(const char* arg, void* data, unsigned sz)
  1216. {
  1217. unsigned int chunk;
  1218. unsigned long long chunk_data_sz;
  1219. sparse_header_t *sparse_header;
  1220. chunk_header_t *chunk_header;
  1221. uint32_t total_blocks = 0;
  1222. unsigned long long ptn = 0;
  1223. unsigned long long size = 0;
  1224. int index = INVALID_PTN;
  1225. nand_arg_t sto_arg;
  1226. sto_arg.img_type = get_nand_image_type(arg);
  1227. unsigned int crc_value;
  1228. unsigned int fill_value;
  1229. data_cache_t cache_inst;
  1230. cache_inst.len = get_cache_size();
  1231. cache_inst.base = (unsigned char*)memalign(128, cache_inst.len);
  1232. cache_inst.offset = 0;
  1233. cache_inst.is_first_write = true;
  1234. cache_inst.valid_data = false;
  1235. cache = &cache_inst;
  1236. index = partition_get_index(arg);
  1237. sto_arg.ptn = partition_get_offset(index);
  1238. if (sto_arg.ptn == (unsigned long long)(-1)) {
  1239. set_response_msg("partition table doesn't exist");
  1240. goto exit;
  1241. }
  1242. sto_arg.size = partition_get_size(index);
  1243. /* Read and skip over sparse image header */
  1244. sparse_header = (sparse_header_t *) data;
  1245. dprintf(ALWAYS, "Image size span 0x%llx, partition size 0x%llx\n", (unsigned long long)sparse_header->total_blks*sparse_header->blk_sz, sto_arg.size);
  1246. if ((unsigned long long)sparse_header->total_blks*sparse_header->blk_sz > sto_arg.size) {
  1247. set_response_msg("sparse image size span overflow.");
  1248. goto exit;
  1249. }
  1250. data += sparse_header->file_hdr_sz;
  1251. if (sparse_header->file_hdr_sz > sizeof(sparse_header_t)) {
  1252. /* Skip the remaining bytes in a header that is longer than
  1253. * we expected.
  1254. */
  1255. data += (sparse_header->file_hdr_sz - sizeof(sparse_header_t));
  1256. }
  1257. cache->blocks_per_cache = (cache->len/sparse_header->blk_sz);
  1258. dprintf (ALWAYS, "=== Sparse Image Header ===\n");
  1259. dprintf (ALWAYS, "magic: 0x%x\n", sparse_header->magic);
  1260. dprintf (ALWAYS, "major_version: 0x%x\n", sparse_header->major_version);
  1261. dprintf (ALWAYS, "minor_version: 0x%x\n", sparse_header->minor_version);
  1262. dprintf (ALWAYS, "file_hdr_sz: %d\n", sparse_header->file_hdr_sz);
  1263. dprintf (ALWAYS, "chunk_hdr_sz: %d\n", sparse_header->chunk_hdr_sz);
  1264. dprintf (ALWAYS, "blk_sz: %d\n", sparse_header->blk_sz);
  1265. dprintf (ALWAYS, "total_blks: %d\n", sparse_header->total_blks);
  1266. dprintf (ALWAYS, "total_chunks: %d\n", sparse_header->total_chunks);
  1267. display_info("\nWriting Flash ... ");
  1268. /* Start processing chunks */
  1269. for (chunk=0; chunk<sparse_header->total_chunks; chunk++) {
  1270. /* Read and skip over chunk header */
  1271. chunk_header = (chunk_header_t *) data;
  1272. data += sizeof(chunk_header_t);
  1273. //dprintf (ALWAYS, "=== Chunk Header ===\n");
  1274. //dprintf (ALWAYS, "chunk_type: 0x%x\n", chunk_header->chunk_type);
  1275. //dprintf (ALWAYS, "chunk_data_sz: 0x%x\n", chunk_header->chunk_sz);
  1276. //dprintf (ALWAYS, "total_size: 0x%x\n", chunk_header->total_sz);
  1277. if (sparse_header->chunk_hdr_sz > sizeof(chunk_header_t)) {
  1278. /* Skip the remaining bytes in a header that is longer than
  1279. * we expected.
  1280. */
  1281. data += (sparse_header->chunk_hdr_sz - sizeof(chunk_header_t));
  1282. }
  1283. chunk_data_sz = (unsigned long long)(sparse_header->blk_sz&0xFFFFFFFF);
  1284. chunk_data_sz = chunk_data_sz * chunk_header->chunk_sz;
  1285. switch (chunk_header->chunk_type) {
  1286. case CHUNK_TYPE_RAW:
  1287. if (chunk_header->total_sz != (sparse_header->chunk_hdr_sz +
  1288. chunk_data_sz)) {
  1289. //fastboot_fail("Bogus chunk size for chunk type Raw");
  1290. goto exit;
  1291. }
  1292. if (!cached_write_data(&total_blocks, data, chunk_data_sz, CHUNK_TYPE_RAW, sparse_header->blk_sz, (void*)&sto_arg)) {
  1293. set_response_msg("storage write failed.");
  1294. goto exit;
  1295. }
  1296. data += chunk_data_sz;
  1297. break;
  1298. case CHUNK_TYPE_DONT_CARE:
  1299. if (!cached_write_data(&total_blocks, 0, chunk_data_sz, CHUNK_TYPE_DONT_CARE, sparse_header->blk_sz, (void*)&sto_arg)) {
  1300. set_response_msg("storage write failed.");
  1301. goto exit;
  1302. }
  1303. break;
  1304. case CHUNK_TYPE_CRC:
  1305. crc_value = *(unsigned int*)data;
  1306. data += 4;
  1307. break;
  1308. case CHUNK_TYPE_FILL:
  1309. fill_value = *(unsigned int*)data;
  1310. if (!cached_write_data(&total_blocks, (char*)&fill_value, chunk_data_sz, CHUNK_TYPE_FILL, sparse_header->blk_sz, (void*)&sto_arg)) {
  1311. set_response_msg("storage write failed.");
  1312. goto exit;
  1313. }
  1314. data += 4; //data length is 4.
  1315. break;
  1316. default:
  1317. set_response_msg("Unknown chunk type");
  1318. goto exit;
  1319. }
  1320. display_progress("\rWrite Data", total_blocks*sparse_header->blk_sz, sparse_header->total_blks*sparse_header->blk_sz);
  1321. }
  1322. /******************/
  1323. //last cache
  1324. if (cache->offset != 0) {
  1325. #if defined(MTK_MLC_NAND_SUPPORT)
  1326. if (nand_write_img((u64)(sto_arg.ptn + ((unsigned long long)total_blocks*sparse_header->blk_sz)), (char*)cache->base, cache->offset,sto_arg.size,sto_arg.img_type))
  1327. #else
  1328. if (nand_write_img((u32)(sto_arg.ptn + ((unsigned long long)total_blocks*sparse_header->blk_sz)), (char*)cache->base, cache->offset,sto_arg.size,sto_arg.img_type))
  1329. #endif
  1330. total_blocks += cache->offset/sparse_header->blk_sz;
  1331. }
  1332. /******************/
  1333. dprintf(ALWAYS, "Wrote %d blocks, expected to write %d blocks\n",
  1334. total_blocks, sparse_header->total_blks);
  1335. if (total_blocks != sparse_header->total_blks) {
  1336. set_response_msg("sparse image write failure");
  1337. } else {
  1338. display_info("\n\nOK");
  1339. //fastboot_okay("");
  1340. if (cache->base) free(cache->base);
  1341. return true;
  1342. }
  1343. exit:
  1344. if (cache->base) free(cache->base);
  1345. return false;
  1346. }
  1347. #endif
  1348. /**********END********/
  1349. #ifdef MTK_ULTRA_FLASH
  1350. #define MAX_SPECIAL_P 17
  1351. char* special_partition[MAX_SPECIAL_P] = {
  1352. "preloader", "boot", "boot0", "boot1", "tee", "tee1", "bootloader"
  1353. , "tee2", "lk", "logo", "atf", "recovery", "partition", "singlebootloader", "gpt", "pgpt","mbr"
  1354. };
  1355. bool is_special_partition(const char* partition)
  1356. {
  1357. int idx = 0;
  1358. for(; idx<MAX_SPECIAL_P; ++idx)
  1359. {
  1360. if (strnicmp(special_partition[idx], partition, 32) == 0)
  1361. {
  1362. return true;
  1363. }
  1364. }
  1365. return false;
  1366. }
  1367. char* trim_space(const char *str)
  1368. {
  1369. char* p = (char*)str;
  1370. if(p == NULL)return NULL;
  1371. while(*p && (*p==' ' || *p == '\t'))
  1372. {
  1373. ++p;
  1374. }
  1375. return p;
  1376. }
  1377. extern void fastboot_update_var(const char *name, const char *value);
  1378. extern const char * fastboot_get_var(const char *name);
  1379. void cmd_oem_ultra_flash(const char *arg, void *data, unsigned sz)
  1380. {
  1381. char response[MAX_RSP_SIZE];
  1382. if(!g_ultra_flash_enable)
  1383. {
  1384. snprintf(response, MAX_RSP_SIZE, "Ultra-flash Disabled. [%s]", fastboot_get_var("max-download-size"));
  1385. fastboot_info(response);
  1386. fastboot_okay("");
  1387. return;
  1388. }
  1389. char* part = trim_space(arg);
  1390. if(strnlen(part, MAX_PARTITION_NAME_LEN+3) >= MAX_PARTITION_NAME_LEN)
  1391. {
  1392. fastboot_fail("name too long.");
  1393. return;
  1394. }
  1395. memset(partition_name_history, 0, MAX_PARTITION_NAME_LEN);
  1396. partition_name_history_len = strnlen(part, MAX_PARTITION_NAME_LEN-1);
  1397. memcpy(partition_name_history, part, partition_name_history_len);
  1398. switch_max_download_len((partition_name_history_len != 0) && (!is_special_partition(partition_name_history)));
  1399. snprintf(response, MAX_RSP_SIZE, "%s. [%s]", partition_name_history, fastboot_get_var("max-download-size"));
  1400. fastboot_info(response);
  1401. fastboot_okay("");
  1402. }
  1403. void switch_max_download_len(bool ultra_en)
  1404. {
  1405. static const char* dl_max_str_history = NULL;
  1406. static const char* dl_max_str = "0x200000000";
  1407. if(dl_max_str_history == NULL)
  1408. {
  1409. dl_max_str_history = fastboot_get_var("max-download-size");
  1410. }
  1411. fastboot_update_var("max-download-size", ultra_en? dl_max_str:dl_max_str_history);
  1412. }
  1413. void cmd_oem_ultra_flash_en(const char *arg, void *data, unsigned sz)
  1414. {
  1415. char response[MAX_RSP_SIZE];
  1416. if (!strncmp(arg, " 1", strlen(" 1")))
  1417. {
  1418. //turn ultra flash on
  1419. fastboot_info("Enable ultra-flash.");
  1420. g_ultra_flash_enable = true;
  1421. }
  1422. else if (!strncmp(arg, " 0", strlen(" 0")))
  1423. {
  1424. //turn ultra flash off
  1425. fastboot_info("Disable ultra-flash.");
  1426. g_ultra_flash_enable = false;
  1427. } else {
  1428. snprintf(response, MAX_RSP_SIZE, "\tCurrent ultra-flash setting:%s",
  1429. g_ultra_flash_enable ? "Enabled" : "Disabled");
  1430. fastboot_info(response);
  1431. }
  1432. fastboot_okay("");
  1433. }
  1434. extern char * strncpy(char *dest, char const *src, size_t count);
  1435. bool cmd_download_ultra(const char *arg, void *data, unsigned sz)
  1436. {
  1437. int index = INVALID_PTN;
  1438. status_t status = STATUS_OK;
  1439. char response[MAX_RSP_SIZE];
  1440. uint64 len = hex2uint64(arg);
  1441. if (!power_check())
  1442. {
  1443. fastboot_fail("low power, need battery charging.");
  1444. return false;
  1445. }
  1446. init_display_xy();
  1447. snprintf(response, MAX_RSP_SIZE, "DATA%08llx", len);
  1448. if (usb_write(response, strlen(response)) < 0) {
  1449. return false;
  1450. }
  1451. display_info("USB Bulk Transferring... ");
  1452. LOGI("[%s]", partition_name_history);
  1453. struct partition_info_struct part_info;
  1454. memset(&part_info, 0, sizeof(struct partition_info_struct));
  1455. index = partition_get_index(partition_name_history);
  1456. if (index == INVALID_PTN)
  1457. {
  1458. fastboot_fail("This partition doesn't exist");
  1459. return false;
  1460. }
  1461. strncpy((char*)part_info.name, partition_name_history, MAX_PARTITION_NAME_LEN);
  1462. part_info.base_addr = partition_get_offset(index);
  1463. if (part_info.base_addr == (unsigned long long)(-1))
  1464. {
  1465. fastboot_fail("partition table doesn't exist");
  1466. return false;
  1467. }
  1468. part_info.part_id = partition_get_region(index);
  1469. part_info.max_size = partition_get_size(index);
  1470. LOGI("download part_name[%s] base_addr[0x%llx] part_max_sz[0x%llx] down_len [0x%llx]\n",
  1471. part_info.name, part_info.base_addr, part_info.max_size, len);
  1472. TIME_START;
  1473. status = download_data(len, &part_info);
  1474. if(FAIL(status))
  1475. {
  1476. snprintf(response, MAX_RSP_SIZE, "Transmission FAIL: [%d]", status);
  1477. fastboot_fail_wrapper(response);
  1478. fastboot_state = STATE_ERROR;
  1479. return false;
  1480. }
  1481. fastboot_ok_wrapper("Transmission OK", len);
  1482. return true;
  1483. }
  1484. void* get_available_ram_base()
  1485. {
  1486. return download_base;
  1487. }
  1488. #endif
  1489. /*LXO: END!Download related command*/