cmd_fastboot.c 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883
  1. /*
  2. * Copyright 2008 - 2009 (C) Wind River Systems, Inc.
  3. * Tom Rix <Tom.Rix@windriver.com>
  4. *
  5. * Copyright (C) 2010-2012 Freescale Semiconductor, Inc.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20. * MA 02111-1307 USA
  21. *
  22. * Part of the rx_handler were copied from the Android project.
  23. * Specifically rx command parsing in the usb_rx_data_complete
  24. * function of the file bootable/bootloader/legacy/usbloader/usbloader.c
  25. *
  26. * The logical naming of flash comes from the Android project
  27. * Thse structures and functions that look like fastboot_flash_*
  28. * They come from bootable/bootloader/legacy/libboot/flash.c
  29. *
  30. * This is their Copyright:
  31. *
  32. * Copyright (C) 2008 The Android Open Source Project
  33. * All rights reserved.
  34. *
  35. * Redistribution and use in source and binary forms, with or without
  36. * modification, are permitted provided that the following conditions
  37. * are met:
  38. * * Redistributions of source code must retain the above copyright
  39. * notice, this list of conditions and the following disclaimer.
  40. * * Redistributions in binary form must reproduce the above copyright
  41. * notice, this list of conditions and the following disclaimer in
  42. * the documentation and/or other materials provided with the
  43. * distribution.
  44. *
  45. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  46. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  47. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  48. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  49. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  50. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  51. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  52. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  53. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  54. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  55. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  56. * SUCH DAMAGE.
  57. */
  58. #include <asm/byteorder.h>
  59. #include <common.h>
  60. #include <command.h>
  61. #include <nand.h>
  62. #include <fastboot.h>
  63. #include <environment.h>
  64. #ifdef CONFIG_FASTBOOT
  65. /* Use do_reset for fastboot's 'reboot' command */
  66. extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
  67. /* Use do_nand for fastboot's flash commands */
  68. #if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  69. extern int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
  70. #elif defined(CONFIG_FASTBOOT_STORAGE_EMMC_SATA)
  71. extern int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
  72. #if defined(CONFIG_CMD_SATA)
  73. extern int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
  74. #endif
  75. extern env_t *env_ptr;
  76. #endif
  77. //extern int do_booti(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
  78. /* Use do_setenv and do_saveenv to permenantly save data */
  79. //int do_saveenv(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
  80. int do_setenv(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
  81. /* Use do_bootm and do_go for fastboot's 'boot' command */
  82. int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
  83. int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
  84. /* Forward decl */
  85. static int tx_handler(void);
  86. static int rx_handler(const unsigned char *buffer, unsigned int buffer_size);
  87. static void reset_handler(void);
  88. static struct cmd_fastboot_interface interface = {
  89. .rx_handler = rx_handler,
  90. .reset_handler = reset_handler,
  91. .product_name = NULL,
  92. .serial_no = NULL,
  93. .nand_block_size = 0,
  94. .transfer_buffer = (unsigned char *)0xffffffff,
  95. .transfer_buffer_size = 0,
  96. };
  97. extern struct fastboot_device_info fastboot_devinfo;
  98. static unsigned int download_size;
  99. static unsigned int download_bytes;
  100. static unsigned int download_bytes_unpadded;
  101. static unsigned int download_error;
  102. static unsigned int continue_booting;
  103. static unsigned int upload_size;
  104. static unsigned int upload_bytes;
  105. static unsigned int upload_error;
  106. /* To support the Android-style naming of flash */
  107. #define MAX_PTN 16
  108. #define MMC_SATA_BLOCK_SIZE 512
  109. static fastboot_ptentry ptable[MAX_PTN];
  110. static unsigned int pcount;
  111. static int static_pcount = -1;
  112. #ifdef CONFIG_FASTBOOT_STORAGE_NAND
  113. static void set_env(char *var, char *val)
  114. {
  115. char *setenv[4] = { "setenv", NULL, NULL, NULL, };
  116. setenv[1] = var;
  117. setenv[2] = val;
  118. do_setenv(NULL, 0, 3, setenv);
  119. }
  120. static void save_env(struct fastboot_ptentry *ptn,
  121. char *var, char *val)
  122. {
  123. char start[32], length[32];
  124. char ecc_type[32];
  125. char *lock[5] = { "nand", "lock", NULL, NULL, NULL, };
  126. char *unlock[5] = { "nand", "unlock", NULL, NULL, NULL, };
  127. char *ecc[4] = { "nand", "ecc", NULL, NULL, };
  128. char *saveenv[2] = { "setenv", NULL, };
  129. lock[2] = unlock[2] = start;
  130. lock[3] = unlock[3] = length;
  131. set_env(var, val);
  132. /* Some flashing requires the nand's ecc to be set */
  133. ecc[2] = ecc_type;
  134. if ((ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC) &&
  135. (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_SW_ECC)) {
  136. /* Both can not be true */
  137. printf("Warning can not do hw and sw ecc for partition '%s'\n",
  138. ptn->name);
  139. printf("Ignoring these flags\n");
  140. } else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC) {
  141. sprintf(ecc_type, "hw");
  142. do_nand(NULL, 0, 3, ecc);
  143. } else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_SW_ECC) {
  144. sprintf(ecc_type, "sw");
  145. do_nand(NULL, 0, 3, ecc);
  146. }
  147. sprintf(start, "0x%x", ptn->start);
  148. sprintf(length, "0x%x", ptn->length);
  149. /* This could be a problem is there is an outstanding lock */
  150. do_nand(NULL, 0, 4, unlock);
  151. //do_saveenv(NULL, 0, 1, saveenv);
  152. do_nand(NULL, 0, 4, lock);
  153. }
  154. static void save_block_values(struct fastboot_ptentry *ptn,
  155. unsigned int offset,
  156. unsigned int size)
  157. {
  158. struct fastboot_ptentry *env_ptn;
  159. char var[64], val[32];
  160. char start[32], length[32];
  161. char ecc_type[32];
  162. char *lock[5] = { "nand", "lock", NULL, NULL, NULL, };
  163. char *unlock[5] = { "nand", "unlock", NULL, NULL, NULL, };
  164. char *ecc[4] = { "nand", "ecc", NULL, NULL, };
  165. char *setenv[4] = { "setenv", NULL, NULL, NULL, };
  166. char *saveenv[2] = { "setenv", NULL, };
  167. setenv[1] = var;
  168. setenv[2] = val;
  169. lock[2] = unlock[2] = start;
  170. lock[3] = unlock[3] = length;
  171. printf("saving it..\n");
  172. if (size == 0) {
  173. /* The error case, where the variables are being unset */
  174. sprintf(var, "%s_nand_offset", ptn->name);
  175. sprintf(val, "");
  176. do_setenv(NULL, 0, 3, setenv);
  177. sprintf(var, "%s_nand_size", ptn->name);
  178. sprintf(val, "");
  179. do_setenv(NULL, 0, 3, setenv);
  180. } else {
  181. /* Normal case */
  182. sprintf(var, "%s_nand_offset", ptn->name);
  183. sprintf(val, "0x%x", offset);
  184. printf("%s %s %s\n", setenv[0], setenv[1], setenv[2]);
  185. do_setenv(NULL, 0, 3, setenv);
  186. sprintf(var, "%s_nand_size", ptn->name);
  187. sprintf(val, "0x%x", size);
  188. printf("%s %s %s\n", setenv[0], setenv[1], setenv[2]);
  189. do_setenv(NULL, 0, 3, setenv);
  190. }
  191. /* Warning :
  192. The environment is assumed to be in a partition named 'enviroment'.
  193. It is very possible that your board stores the enviroment
  194. someplace else. */
  195. env_ptn = fastboot_flash_find_ptn("environment");
  196. if (env_ptn) {
  197. /* Some flashing requires the nand's ecc to be set */
  198. ecc[2] = ecc_type;
  199. if ((env_ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC) &&
  200. (env_ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_SW_ECC)) {
  201. /* Both can not be true */
  202. printf("Warning can not do hw and sw ecc for \
  203. partition '%s'\n", ptn->name);
  204. printf("Ignoring these flags\n");
  205. } else if (env_ptn->flags &
  206. FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC) {
  207. sprintf(ecc_type, "hw");
  208. do_nand(NULL, 0, 3, ecc);
  209. } else if (env_ptn->flags &
  210. FASTBOOT_PTENTRY_FLAGS_WRITE_SW_ECC) {
  211. sprintf(ecc_type, "sw");
  212. do_nand(NULL, 0, 3, ecc);
  213. }
  214. sprintf(start, "0x%x", env_ptn->start);
  215. sprintf(length, "0x%x", env_ptn->length);
  216. /* This could be a problem is there is an outstanding lock */
  217. do_nand(NULL, 0, 4, unlock);
  218. }
  219. //do_saveenv(NULL, 0, 1, saveenv);
  220. if (env_ptn)
  221. do_nand(NULL, 0, 4, lock);
  222. }
  223. #else
  224. /* will do later */
  225. #endif
  226. static void reset_handler ()
  227. {
  228. /* If there was a download going on, bail */
  229. download_size = 0;
  230. download_bytes = 0;
  231. download_bytes_unpadded = 0;
  232. download_error = 0;
  233. continue_booting = 0;
  234. upload_size = 0;
  235. upload_bytes = 0;
  236. upload_error = 0;
  237. }
  238. #ifdef CONFIG_FASTBOOT_STORAGE_NAND
  239. /* When save = 0, just parse. The input is unchanged
  240. When save = 1, parse and do the save. The input is changed */
  241. static int parse_env(void *ptn, char *err_string, int save, int debug)
  242. {
  243. int ret = 1;
  244. unsigned int sets = 0;
  245. unsigned int comment_start = 0;
  246. char *var = NULL;
  247. char *var_end = NULL;
  248. char *val = NULL;
  249. char *val_end = NULL;
  250. unsigned int i;
  251. char *buff = (char *)interface.transfer_buffer;
  252. unsigned int size = download_bytes_unpadded;
  253. /* The input does not have to be null terminated.
  254. This will cause a problem in the corner case
  255. where the last line does not have a new line.
  256. Put a null after the end of the input.
  257. WARNING : Input buffer is assumed to be bigger
  258. than the size of the input */
  259. if (save)
  260. buff[size] = 0;
  261. for (i = 0; i < size; i++) {
  262. if (NULL == var) {
  263. /*
  264. * Check for comments, comment ok only on
  265. * mostly empty lines
  266. */
  267. if (buff[i] == '#')
  268. comment_start = 1;
  269. if (comment_start) {
  270. if ((buff[i] == '\r') ||
  271. (buff[i] == '\n')) {
  272. comment_start = 0;
  273. }
  274. } else {
  275. if (!((buff[i] == ' ') ||
  276. (buff[i] == '\t') ||
  277. (buff[i] == '\r') ||
  278. (buff[i] == '\n'))) {
  279. /*
  280. * Normal whitespace before the
  281. * variable
  282. */
  283. var = &buff[i];
  284. }
  285. }
  286. } else if (((NULL == var_end) || (NULL == val)) &&
  287. ((buff[i] == '\r') || (buff[i] == '\n'))) {
  288. /* This is the case when a variable
  289. is unset. */
  290. if (save) {
  291. /* Set the var end to null so the
  292. normal string routines will work
  293. WARNING : This changes the input */
  294. buff[i] = '\0';
  295. save_env(ptn, var, val);
  296. if (debug)
  297. printf("Unsetting %s\n", var);
  298. }
  299. /* Clear the variable so state is parse is back
  300. to initial. */
  301. var = NULL;
  302. var_end = NULL;
  303. sets++;
  304. } else if (NULL == var_end) {
  305. if ((buff[i] == ' ') ||
  306. (buff[i] == '\t'))
  307. var_end = &buff[i];
  308. } else if (NULL == val) {
  309. if (!((buff[i] == ' ') ||
  310. (buff[i] == '\t')))
  311. val = &buff[i];
  312. } else if (NULL == val_end) {
  313. if ((buff[i] == '\r') ||
  314. (buff[i] == '\n')) {
  315. /* look for escaped cr or ln */
  316. if ('\\' == buff[i - 1]) {
  317. /* check for dos */
  318. if ((buff[i] == '\r') &&
  319. (buff[i+1] == '\n'))
  320. buff[i + 1] = ' ';
  321. buff[i - 1] = buff[i] = ' ';
  322. } else {
  323. val_end = &buff[i];
  324. }
  325. }
  326. } else {
  327. sprintf(err_string, "Internal Error");
  328. if (debug)
  329. printf("Internal error at %s %d\n",
  330. __FILE__, __LINE__);
  331. return 1;
  332. }
  333. /* Check if a var / val pair is ready */
  334. if (NULL != val_end) {
  335. if (save) {
  336. /* Set the end's with nulls so
  337. normal string routines will
  338. work.
  339. WARNING : This changes the input */
  340. *var_end = '\0';
  341. *val_end = '\0';
  342. save_env(ptn, var, val);
  343. if (debug)
  344. printf("Setting %s %s\n", var, val);
  345. }
  346. /* Clear the variable so state is parse is back
  347. to initial. */
  348. var = NULL;
  349. var_end = NULL;
  350. val = NULL;
  351. val_end = NULL;
  352. sets++;
  353. }
  354. }
  355. /* Corner case
  356. Check for the case that no newline at end of the input */
  357. if ((NULL != var) &&
  358. (NULL == val_end)) {
  359. if (save) {
  360. /* case of val / val pair */
  361. if (var_end)
  362. *var_end = '\0';
  363. /* else case handled by setting 0 past
  364. the end of buffer.
  365. Similar for val_end being null */
  366. save_env(ptn, var, val);
  367. if (debug) {
  368. if (var_end)
  369. printf("Trailing Setting %s %s\n", var, val);
  370. else
  371. printf("Trailing Unsetting %s\n", var);
  372. }
  373. }
  374. sets++;
  375. }
  376. /* Did we set anything ? */
  377. if (0 == sets)
  378. sprintf(err_string, "No variables set");
  379. else
  380. ret = 0;
  381. return ret;
  382. }
  383. static int saveenv_to_ptn(struct fastboot_ptentry *ptn, char *err_string)
  384. {
  385. int ret = 1;
  386. int save = 0;
  387. int debug = 0;
  388. /* err_string is only 32 bytes
  389. Initialize with a generic error message. */
  390. sprintf(err_string, "%s", "Unknown Error");
  391. /* Parse the input twice.
  392. Only save to the enviroment if the entire input if correct */
  393. save = 0;
  394. if (0 == parse_env(ptn, err_string, save, debug)) {
  395. save = 1;
  396. ret = parse_env(ptn, err_string, save, debug);
  397. }
  398. return ret;
  399. }
  400. static void set_ptn_ecc(struct fastboot_ptentry *ptn)
  401. {
  402. char ecc_type[32];
  403. char *ecc[4] = {"nand", "ecc", NULL, NULL, };
  404. /* Some flashing requires the nand's ecc to be set */
  405. ecc[2] = ecc_type;
  406. if ((ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC) &&
  407. (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_SW_ECC)) {
  408. /* Both can not be true */
  409. printf("Warning can not do hw and sw ecc for partition '%s'\n",
  410. ptn->name);
  411. printf("Ignoring these flags\n");
  412. } else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC) {
  413. sprintf(ecc_type, "hw");
  414. do_nand(NULL, 0, 3, ecc);
  415. } else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_SW_ECC) {
  416. sprintf(ecc_type, "sw");
  417. do_nand(NULL, 0, 3, ecc);
  418. }
  419. }
  420. static int write_to_ptn(struct fastboot_ptentry *ptn)
  421. {
  422. int ret = 1;
  423. char start[32], length[32];
  424. char wstart[32], wlength[32], addr[32];
  425. char write_type[32];
  426. int repeat, repeat_max;
  427. char *lock[5] = { "nand", "lock", NULL, NULL, NULL, };
  428. char *unlock[5] = { "nand", "unlock", NULL, NULL, NULL, };
  429. char *write[6] = { "nand", "write", NULL, NULL, NULL, NULL, };
  430. char *erase[5] = { "nand", "erase", NULL, NULL, NULL, };
  431. lock[2] = unlock[2] = erase[2] = start;
  432. lock[3] = unlock[3] = erase[3] = length;
  433. write[1] = write_type;
  434. write[2] = addr;
  435. write[3] = wstart;
  436. write[4] = wlength;
  437. printf("flashing '%s'\n", ptn->name);
  438. /* Which flavor of write to use */
  439. if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_I)
  440. sprintf(write_type, "write.i");
  441. #ifdef CFG_NAND_YAFFS_WRITE
  442. else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS)
  443. sprintf(write_type, "write.yaffs");
  444. #endif
  445. else
  446. sprintf(write_type, "write");
  447. set_ptn_ecc(ptn);
  448. /* Some flashing requires writing the same data in multiple,
  449. consecutive flash partitions */
  450. repeat_max = 1;
  451. if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_REPEAT_MASK) {
  452. if (ptn->flags &
  453. FASTBOOT_PTENTRY_FLAGS_WRITE_CONTIGUOUS_BLOCK) {
  454. printf("Warning can not do both 'contiguous block' and 'repeat' writes for for partition '%s'\n", ptn->name);
  455. printf("Ignoring repeat flag\n");
  456. } else {
  457. repeat_max = ptn->flags &
  458. FASTBOOT_PTENTRY_FLAGS_REPEAT_MASK;
  459. }
  460. }
  461. /* Unlock the whole partition instead of trying to
  462. manage special cases */
  463. sprintf(length, "0x%x", ptn->length * repeat_max);
  464. for (repeat = 0; repeat < repeat_max; repeat++) {
  465. sprintf(start, "0x%x", ptn->start + (repeat * ptn->length));
  466. do_nand(NULL, 0, 4, unlock);
  467. do_nand(NULL, 0, 4, erase);
  468. if ((ptn->flags &
  469. FASTBOOT_PTENTRY_FLAGS_WRITE_NEXT_GOOD_BLOCK) &&
  470. (ptn->flags &
  471. FASTBOOT_PTENTRY_FLAGS_WRITE_CONTIGUOUS_BLOCK)) {
  472. /* Both can not be true */
  473. printf("Warning can not do 'next good block' and \
  474. 'contiguous block' for partition '%s'\n",
  475. ptn->name);
  476. printf("Ignoring these flags\n");
  477. } else if (ptn->flags &
  478. FASTBOOT_PTENTRY_FLAGS_WRITE_NEXT_GOOD_BLOCK) {
  479. /* Keep writing until you get a good block
  480. transfer_buffer should already be aligned */
  481. if (interface.nand_block_size) {
  482. unsigned int blocks = download_bytes /
  483. interface.nand_block_size;
  484. unsigned int i = 0;
  485. unsigned int offset = 0;
  486. sprintf(wlength, "0x%x",
  487. interface.nand_block_size);
  488. while (i < blocks) {
  489. /* Check for overflow */
  490. if (offset >= ptn->length)
  491. break;
  492. /* download's address only advance
  493. if last write was successful */
  494. sprintf(addr, "0x%p",
  495. interface.transfer_buffer +
  496. (i * interface.nand_block_size));
  497. /* nand's address always advances */
  498. sprintf(wstart, "0x%x",
  499. ptn->start + (repeat * ptn->length) + offset);
  500. ret = do_nand(NULL, 0, 5, write);
  501. if (ret)
  502. break;
  503. else
  504. i++;
  505. /* Go to next nand block */
  506. offset += interface.nand_block_size;
  507. }
  508. } else {
  509. printf("Warning nand block size can not be 0 \
  510. when using 'next good block' for \
  511. partition '%s'\n", ptn->name);
  512. printf("Ignoring write request\n");
  513. }
  514. } else if (ptn->flags &
  515. FASTBOOT_PTENTRY_FLAGS_WRITE_CONTIGUOUS_BLOCK) {
  516. /* Keep writing until you get a good block
  517. transfer_buffer should already be aligned */
  518. if (interface.nand_block_size) {
  519. if (0 == nand_curr_device) {
  520. nand_info_t *nand;
  521. unsigned long off;
  522. unsigned int ok_start;
  523. nand = &nand_info[nand_curr_device];
  524. printf("\nDevice %d bad blocks:\n",
  525. nand_curr_device);
  526. /* Initialize the ok_start to the
  527. start of the partition
  528. Then try to find a block large
  529. enough for the download */
  530. ok_start = ptn->start;
  531. /* It is assumed that the start and
  532. length are multiples of block size */
  533. for (off = ptn->start;
  534. off < ptn->start + ptn->length;
  535. off += nand->erasesize) {
  536. if (nand_block_isbad(nand, off)) {
  537. /* Reset the ok_start
  538. to the next block */
  539. ok_start = off +
  540. nand->erasesize;
  541. }
  542. /* Check if we have enough
  543. blocks */
  544. if ((ok_start - off) >=
  545. download_bytes)
  546. break;
  547. }
  548. /* Check if there is enough space */
  549. if (ok_start + download_bytes <=
  550. ptn->start + ptn->length) {
  551. sprintf(addr, "0x%p",
  552. interface.transfer_buffer);
  553. sprintf(wstart, "0x%x", ok_start);
  554. sprintf(wlength, "0x%x", download_bytes);
  555. ret = do_nand(NULL, 0, 5, write);
  556. /* Save the results into an
  557. environment variable on the
  558. format
  559. ptn_name + 'offset'
  560. ptn_name + 'size' */
  561. if (ret) {
  562. /* failed */
  563. save_block_values(ptn, 0, 0);
  564. } else {
  565. /* success */
  566. save_block_values(ptn, ok_start, download_bytes);
  567. }
  568. } else {
  569. printf("Error could not find enough contiguous space in partition '%s' \n", ptn->name);
  570. printf("Ignoring write request\n");
  571. }
  572. } else {
  573. /* TBD : Generalize flash handling */
  574. printf("Error only handling 1 NAND per board");
  575. printf("Ignoring write request\n");
  576. }
  577. } else {
  578. printf("Warning nand block size can not be 0 \
  579. when using 'continuous block' for \
  580. partition '%s'\n", ptn->name);
  581. printf("Ignoring write request\n");
  582. }
  583. } else {
  584. /* Normal case */
  585. sprintf(addr, "0x%p", interface.transfer_buffer);
  586. sprintf(wstart, "0x%x", ptn->start +
  587. (repeat * ptn->length));
  588. sprintf(wlength, "0x%x", download_bytes);
  589. #ifdef CFG_NAND_YAFFS_WRITE
  590. if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS)
  591. sprintf(wlength, "0x%x",
  592. download_bytes_unpadded);
  593. #endif
  594. ret = do_nand(NULL, 0, 5, write);
  595. if (0 == repeat) {
  596. if (ret) /* failed */
  597. save_block_values(ptn, 0, 0);
  598. else /* success */
  599. save_block_values(ptn, ptn->start,
  600. download_bytes);
  601. }
  602. }
  603. do_nand(NULL, 0, 4, lock);
  604. if (ret)
  605. break;
  606. }
  607. return ret;
  608. }
  609. #else
  610. /* will do environment writing/saving later */
  611. #endif
  612. static int tx_handler(void)
  613. {
  614. if (upload_size) {
  615. int bytes_written;
  616. bytes_written = fastboot_tx(interface.transfer_buffer +
  617. upload_bytes, upload_size -
  618. upload_bytes);
  619. if (bytes_written > 0) {
  620. upload_bytes += bytes_written;
  621. /* Check if this is the last */
  622. if (upload_bytes == upload_size) {
  623. /* Reset upload */
  624. upload_size = 0;
  625. upload_bytes = 0;
  626. upload_error = 0;
  627. }
  628. }
  629. }
  630. return upload_error;
  631. }
  632. static int rx_handler (const unsigned char *buffer, unsigned int buffer_size)
  633. {
  634. int ret = 1, temp_len = 0;
  635. /* Use 65 instead of 64
  636. null gets dropped
  637. strcpy's need the extra byte */
  638. char response[65];
  639. if (download_size) {
  640. /* Something to download */
  641. if (buffer_size) {
  642. /* Handle possible overflow */
  643. unsigned int transfer_size =
  644. download_size - download_bytes;
  645. if (buffer_size < transfer_size)
  646. transfer_size = buffer_size;
  647. /* Save the data to the transfer buffer */
  648. memcpy(interface.transfer_buffer + download_bytes,
  649. buffer, transfer_size);
  650. download_bytes += transfer_size;
  651. /* Check if transfer is done */
  652. if (download_bytes >= download_size) {
  653. /* Reset global transfer variable,
  654. Keep download_bytes because it will be
  655. used in the next possible flashing command */
  656. download_size = 0;
  657. if (download_error) {
  658. /* There was an earlier error */
  659. sprintf(response, "ERROR");
  660. } else {
  661. /* Everything has transferred,
  662. send the OK response */
  663. sprintf(response, "OKAY");
  664. }
  665. fastboot_tx_status(response, strlen(response));
  666. printf("\ndownloading of %d bytes finished\n",
  667. download_bytes);
  668. #if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  669. /* Pad to block length
  670. In most cases, padding the download to be
  671. block aligned is correct. The exception is
  672. when the following flash writes to the oob
  673. area. This happens when the image is a
  674. YAFFS image. Since we do not know what
  675. the download is until it is flashed,
  676. go ahead and pad it, but save the true
  677. size in case if should have
  678. been unpadded */
  679. download_bytes_unpadded = download_bytes;
  680. if (interface.nand_block_size) {
  681. if (download_bytes %
  682. interface.nand_block_size) {
  683. unsigned int pad = interface.nand_block_size - (download_bytes % interface.nand_block_size);
  684. unsigned int i;
  685. for (i = 0; i < pad; i++) {
  686. if (download_bytes >= interface.transfer_buffer_size)
  687. break;
  688. interface.transfer_buffer[download_bytes] = 0;
  689. download_bytes++;
  690. }
  691. }
  692. }
  693. #endif
  694. }
  695. /* Provide some feedback */
  696. if (download_bytes &&
  697. 0 == (download_bytes %
  698. (16 * interface.nand_block_size))) {
  699. /* Some feeback that the
  700. download is happening */
  701. if (download_error)
  702. printf("X");
  703. else
  704. printf(".");
  705. if (0 == (download_bytes %
  706. (80 * 16 *
  707. interface.nand_block_size)))
  708. printf("\n");
  709. }
  710. } else {
  711. /* Ignore empty buffers */
  712. printf("Warning empty download buffer\n");
  713. printf("Ignoring\n");
  714. }
  715. ret = 0;
  716. } else {
  717. /* A command */
  718. /* Cast to make compiler happy with string functions */
  719. const char *cmdbuf = (char *) buffer;
  720. printf("cmdbuf: %s\n", cmdbuf);
  721. /* Generic failed response */
  722. sprintf(response, "FAIL");
  723. /* reboot
  724. Reboot the board. */
  725. if (memcmp(cmdbuf, "reboot", 6) == 0) {
  726. sprintf(response, "OKAY");
  727. fastboot_tx_status(response, strlen(response));
  728. udelay(1000000); /* 1 sec */
  729. do_reset(NULL, 0, 0, NULL);
  730. /* This code is unreachable,
  731. leave it to make the compiler happy */
  732. return 0;
  733. }
  734. /* getvar
  735. Get common fastboot variables
  736. Board has a chance to handle other variables */
  737. if (memcmp(cmdbuf, "getvar:", 7) == 0) {
  738. strcpy(response, "OKAY");
  739. temp_len = strlen("getvar:");
  740. if (!strcmp(cmdbuf + temp_len, "version")) {
  741. strcpy(response + 4, FASTBOOT_VERSION);
  742. } else if (!strcmp(cmdbuf + temp_len,
  743. "product")) {
  744. if (interface.product_name)
  745. strcpy(response + 4, interface.product_name);
  746. } else if (!strcmp(cmdbuf + temp_len,
  747. "serialno")) {
  748. if (interface.serial_no)
  749. strcpy(response + 4, interface.serial_no);
  750. } else if (!strcmp(cmdbuf + temp_len,
  751. "downloadsize")) {
  752. if (interface.transfer_buffer_size)
  753. sprintf(response + 4, "0x%x",
  754. interface.transfer_buffer_size);
  755. } else {
  756. fastboot_getvar(cmdbuf + 7, response + 4);
  757. }
  758. ret = 0;
  759. }
  760. /* erase
  761. Erase a register flash partition
  762. Board has to set up flash partitions */
  763. if (memcmp(cmdbuf, "erase:", 6) == 0) {
  764. #if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  765. struct fastboot_ptentry *ptn;
  766. ptn = fastboot_flash_find_ptn(cmdbuf + 6);
  767. if (ptn == 0) {
  768. sprintf(response, "FAILpartition does not exist");
  769. } else {
  770. char start[32], length[32];
  771. int status, repeat, repeat_max;
  772. printf("erasing '%s'\n", ptn->name);
  773. char *lock[5] = { "nand", "lock", NULL, NULL, NULL, };
  774. char *unlock[5] = { "nand", "unlock", NULL, NULL, NULL, };
  775. char *erase[5] = { "nand", "erase", NULL, NULL, NULL, };
  776. lock[2] = unlock[2] = erase[2] = start;
  777. lock[3] = unlock[3] = erase[3] = length;
  778. repeat_max = 1;
  779. if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_REPEAT_MASK)
  780. repeat_max = ptn->flags & FASTBOOT_PTENTRY_FLAGS_REPEAT_MASK;
  781. sprintf(length, "0x%x", ptn->length);
  782. for (repeat = 0; repeat < repeat_max;
  783. repeat++) {
  784. sprintf(start, "0x%x",
  785. ptn->start +
  786. (repeat * ptn->length));
  787. do_nand(NULL, 0, 4, unlock);
  788. status = do_nand(NULL, 0, 4, erase);
  789. do_nand(NULL, 0, 4, lock);
  790. if (status)
  791. break;
  792. }
  793. if (status) {
  794. sprintf(response,
  795. "FAILfailed to erase partition");
  796. } else {
  797. printf("partition '%s' erased\n", ptn->name);
  798. sprintf(response, "OKAY");
  799. }
  800. }
  801. ret = 0;
  802. #else
  803. printf("Not support erase command for EMMC\n");
  804. ret = -1;
  805. #endif
  806. }
  807. /* download
  808. download something ..
  809. What happens to it depends on the next command after data */
  810. if (memcmp(cmdbuf, "download:", 9) == 0) {
  811. /* save the size */
  812. download_size = simple_strtoul(cmdbuf + 9, NULL, 16);
  813. /* Reset the bytes count, now it is safe */
  814. download_bytes = 0;
  815. /* Reset error */
  816. download_error = 0;
  817. printf("Starting download of %d bytes\n",
  818. download_size);
  819. if (0 == download_size) {
  820. /* bad user input */
  821. sprintf(response, "FAILdata invalid size");
  822. } else if (download_size >
  823. interface.transfer_buffer_size) {
  824. /* set download_size to 0 because this is an error */
  825. download_size = 0;
  826. sprintf(response, "FAILdata too large");
  827. } else {
  828. /* The default case, the transfer fits
  829. completely in the interface buffer */
  830. sprintf(response, "DATA%08x", download_size);
  831. }
  832. ret = 0;
  833. }
  834. /* boot
  835. boot what was downloaded
  836. WARNING WARNING WARNING
  837. This is not what you expect.
  838. The fastboot client does its own packaging of the
  839. kernel. The layout is defined in the android header
  840. file bootimage.h. This layeout is copiedlooks like this,
  841. **
  842. ** +-----------------+
  843. ** | boot header | 1 page
  844. ** +-----------------+
  845. ** | kernel | n pages
  846. ** +-----------------+
  847. ** | ramdisk | m pages
  848. ** +-----------------+
  849. ** | second stage | o pages
  850. ** +-----------------+
  851. **
  852. We only care about the kernel.
  853. So we have to jump past a page.
  854. What is a page size ?
  855. The fastboot client uses 2048
  856. The is the default value of
  857. CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE
  858. */
  859. if (memcmp(cmdbuf, "boot", 4) == 0) {
  860. if ((download_bytes) &&
  861. (CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE <
  862. download_bytes)) {
  863. char start[32];
  864. char *booti_args[4] = {"booti", NULL, "boot", NULL};
  865. /*
  866. * Use this later to determine if a command line was passed
  867. * for the kernel.
  868. */
  869. /* struct fastboot_boot_img_hdr *fb_hdr = */
  870. /* (struct fastboot_boot_img_hdr *) interface.transfer_buffer; */
  871. /* Skip the mkbootimage header */
  872. /* image_header_t *hdr = */
  873. /* (image_header_t *) */
  874. /* &interface.transfer_buffer[CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE]; */
  875. booti_args[1] = start;
  876. sprintf(start, "0x%x", (unsigned int)interface.transfer_buffer);
  877. /* Execution should jump to kernel so send the response
  878. now and wait a bit. */
  879. sprintf(response, "OKAY");
  880. fastboot_tx_status(response, strlen(response));
  881. printf("Booting kernel...\n");
  882. /* Reserve for further use, this can
  883. * be more convient for developer. */
  884. /* if (strlen ((char *) &fb_hdr->cmdline[0])) */
  885. /* set_env("bootargs", (char *) &fb_hdr->cmdline[0]); */
  886. /* boot the boot.img */
  887. //do_booti(NULL, 0, 3, booti_args);
  888. }
  889. sprintf(response, "FAILinvalid boot image");
  890. ret = 0;
  891. }
  892. /* flash
  893. Flash what was downloaded */
  894. if (memcmp(cmdbuf, "flash:", 6) == 0) {
  895. #if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  896. if (download_bytes) {
  897. struct fastboot_ptentry *ptn;
  898. ptn = fastboot_flash_find_ptn(cmdbuf + 6);
  899. if (ptn == 0) {
  900. sprintf(response, "FAILpartition does not exist");
  901. } else if ((download_bytes > ptn->length) &&
  902. !(ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV)) {
  903. sprintf(response, "FAILimage too large for partition");
  904. /* TODO : Improve check for yaffs write */
  905. } else {
  906. /* Check if this is not really a flash write
  907. but rather a saveenv */
  908. if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV) {
  909. /* Since the response can only be 64 bytes,
  910. there is no point in having a large error message. */
  911. char err_string[32];
  912. if (saveenv_to_ptn(ptn, &err_string[0])) {
  913. printf("savenv '%s' failed : %s\n", ptn->name, err_string);
  914. sprintf(response, "FAIL%s", err_string);
  915. } else {
  916. printf("partition '%s' saveenv-ed\n", ptn->name);
  917. sprintf(response, "OKAY");
  918. }
  919. } else {
  920. /* Normal case */
  921. if (write_to_ptn(ptn)) {
  922. printf("flashing '%s' failed\n", ptn->name);
  923. sprintf(response, "FAILfailed to flash partition");
  924. } else {
  925. printf("partition '%s' flashed\n", ptn->name);
  926. sprintf(response, "OKAY");
  927. }
  928. }
  929. }
  930. } else {
  931. sprintf(response, "FAILno image downloaded");
  932. }
  933. #elif defined(CONFIG_FASTBOOT_STORAGE_EMMC_SATA)
  934. if (download_bytes) {
  935. struct fastboot_ptentry *ptn;
  936. /* Next is the partition name */
  937. ptn = fastboot_flash_find_ptn(cmdbuf + 6);
  938. if (ptn == 0) {
  939. printf("Partition:'%s' does not exist\n", ptn->name);
  940. sprintf(response, "FAILpartition does not exist");
  941. } else if ((download_bytes >
  942. ptn->length * MMC_SATA_BLOCK_SIZE) &&
  943. !(ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV)) {
  944. printf("Image too large for the partition\n");
  945. sprintf(response, "FAILimage too large for partition");
  946. } else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV) {
  947. /* Check if this is not really a flash write,
  948. * but instead a saveenv
  949. */
  950. unsigned int i = 0;
  951. /* Env file is expected with a NULL delimeter between
  952. * env variables So replace New line Feeds (0x0a) with
  953. * NULL (0x00)
  954. */
  955. printf("Goto write env, flags=0x%x\n",
  956. ptn->flags);
  957. for (i = 0; i < download_bytes; i++) {
  958. if (interface.transfer_buffer[i] == 0x0a)
  959. interface.transfer_buffer[i] = 0x00;
  960. }
  961. memset(env_ptr->data, 0, ENV_SIZE);
  962. memcpy(env_ptr->data, interface.transfer_buffer, download_bytes);
  963. //do_saveenv(NULL, 0, 1, NULL);
  964. printf("saveenv to '%s' DONE!\n", ptn->name);
  965. sprintf(response, "OKAY");
  966. } else {
  967. char source[32], dest[32];
  968. char length[32], slot_no[32];
  969. char part_no[32];
  970. unsigned int temp;
  971. /* Normal case */
  972. if (fastboot_devinfo.type == DEV_MMC)
  973. /* download to mmc */
  974. goto mmc_ops;
  975. else {
  976. /* downaload to sata */
  977. #ifdef CONFIG_CMD_SATA
  978. char *sata_write[5] = {"sata", "write",
  979. NULL, NULL, NULL};
  980. sata_write[2] = source;
  981. sata_write[3] = dest;
  982. sata_write[4] = length;
  983. sprintf(source, "0x%x",
  984. (unsigned int)interface.transfer_buffer);
  985. /* block offset */
  986. sprintf(dest, "0x%x", ptn->start);
  987. /* block count */
  988. temp = (download_bytes +
  989. MMC_SATA_BLOCK_SIZE - 1) /
  990. MMC_SATA_BLOCK_SIZE;
  991. sprintf(length, "0x%x", temp);
  992. if (do_sata(NULL, 0, 5, sata_write)) {
  993. printf("Writing '%s' FAILED!\n",
  994. ptn->name);
  995. sprintf(response,
  996. "FAIL: Write partition");
  997. } else {
  998. printf("Writing '%s' DONE!\n",
  999. ptn->name);
  1000. sprintf(response, "OKAY");
  1001. ret = 0;
  1002. }
  1003. #else
  1004. sprintf(response, "FAIL: Not support");
  1005. #endif
  1006. fastboot_tx_status(response,
  1007. strlen(response));
  1008. return ret; /* End of sata download */
  1009. }
  1010. mmc_ops:
  1011. printf("writing to partition '%s'\n", ptn->name);
  1012. char *mmc_write[5] = {"mmc", "write",
  1013. NULL, NULL, NULL};
  1014. char *mmc_dev[4] = {"mmc", "dev", NULL, NULL};
  1015. mmc_dev[2] = slot_no;
  1016. mmc_dev[3] = part_no;
  1017. mmc_write[2] = source;
  1018. mmc_write[3] = dest;
  1019. mmc_write[4] = length;
  1020. sprintf(slot_no, "%d",
  1021. fastboot_devinfo.dev_id);
  1022. sprintf(source, "0x%x", (unsigned int)interface.transfer_buffer);
  1023. /* partition no */
  1024. sprintf(part_no, "%d",
  1025. ptn->partition_id);
  1026. /* block offset */
  1027. sprintf(dest, "0x%x", ptn->start);
  1028. /* block count */
  1029. temp = (download_bytes +
  1030. MMC_SATA_BLOCK_SIZE - 1) /
  1031. MMC_SATA_BLOCK_SIZE;
  1032. sprintf(length, "0x%x", temp);
  1033. printf("Initializing '%s'\n", ptn->name);
  1034. if(1)
  1035. //if (do_mmcops(NULL, 0, 4, mmc_dev))
  1036. sprintf(response, "FAIL:Init of MMC card");
  1037. else
  1038. sprintf(response, "OKAY");
  1039. printf("Writing '%s'\n", ptn->name);
  1040. if(1) {
  1041. //if (do_mmcops(NULL, 0, 5, mmc_write)) {
  1042. printf("Writing '%s' FAILED!\n", ptn->name);
  1043. sprintf(response, "FAIL: Write partition");
  1044. } else {
  1045. printf("Writing '%s' DONE!\n", ptn->name);
  1046. sprintf(response, "OKAY");
  1047. }
  1048. }
  1049. } else {
  1050. sprintf(response, "FAILno image downloaded");
  1051. }
  1052. #endif
  1053. ret = 0;
  1054. }
  1055. /* continue
  1056. Stop doing fastboot */
  1057. if (memcmp(cmdbuf, "continue", 8) == 0) {
  1058. sprintf(response, "OKAY");
  1059. continue_booting = 1;
  1060. ret = 0;
  1061. }
  1062. /* upload
  1063. Upload just the data in a partition */
  1064. if ((memcmp(cmdbuf, "upload:", 7) == 0) ||
  1065. (memcmp(cmdbuf, "uploadraw:", 10) == 0)) {
  1066. #if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  1067. unsigned int adv, delim_index, len;
  1068. struct fastboot_ptentry *ptn;
  1069. unsigned int is_raw = 0;
  1070. /* Is this a raw read ? */
  1071. if (memcmp(cmdbuf, "uploadraw:", 10) == 0) {
  1072. is_raw = 1;
  1073. adv = 10;
  1074. } else {
  1075. adv = 7;
  1076. }
  1077. /* Scan to the next ':' to find when the size starts */
  1078. len = strlen(cmdbuf);
  1079. for (delim_index = adv;
  1080. delim_index < len; delim_index++) {
  1081. if (cmdbuf[delim_index] == ':') {
  1082. /* WARNING, cmdbuf is being modified. */
  1083. *((char *) &cmdbuf[delim_index]) = 0;
  1084. break;
  1085. }
  1086. }
  1087. ptn = fastboot_flash_find_ptn(cmdbuf + adv);
  1088. if (ptn == 0) {
  1089. sprintf(response,
  1090. "FAILpartition does not exist");
  1091. } else {
  1092. /* This is how much the user is expecting */
  1093. unsigned int user_size;
  1094. /*
  1095. * This is the maximum size needed for
  1096. * this partition
  1097. */
  1098. unsigned int size;
  1099. /* This is the length of the data */
  1100. unsigned int length;
  1101. /*
  1102. * Used to check previous write of
  1103. * the parition
  1104. */
  1105. char env_ptn_length_var[128];
  1106. char *env_ptn_length_val;
  1107. user_size = 0;
  1108. if (delim_index < len)
  1109. user_size =
  1110. simple_strtoul(cmdbuf + delim_index +
  1111. 1, NULL, 16);
  1112. /* Make sure output is padded to block size */
  1113. length = ptn->length;
  1114. sprintf(env_ptn_length_var,
  1115. "%s_nand_size", ptn->name);
  1116. env_ptn_length_val = getenv(env_ptn_length_var);
  1117. if (env_ptn_length_val) {
  1118. length =
  1119. simple_strtoul(env_ptn_length_val,
  1120. NULL, 16);
  1121. /* Catch possible problems */
  1122. if (!length)
  1123. length = ptn->length;
  1124. }
  1125. size = length / interface.nand_block_size;
  1126. size *= interface.nand_block_size;
  1127. if (length % interface.nand_block_size)
  1128. size += interface.nand_block_size;
  1129. if (is_raw)
  1130. size += (size /
  1131. interface.nand_block_size) *
  1132. interface.nand_oob_size;
  1133. if (size > interface.transfer_buffer_size) {
  1134. sprintf(response, "FAILdata too large");
  1135. } else if (user_size == 0) {
  1136. /* Send the data response */
  1137. sprintf(response, "DATA%08x", size);
  1138. } else if (user_size != size) {
  1139. /* This is the wrong size */
  1140. sprintf(response, "FAIL");
  1141. } else {
  1142. /*
  1143. * This is where the transfer
  1144. * buffer is populated
  1145. */
  1146. unsigned char *buf =
  1147. interface.transfer_buffer;
  1148. char start[32], length[32], type[32],
  1149. addr[32];
  1150. char *read[6] = { "nand", NULL, NULL,
  1151. NULL, NULL, NULL, };
  1152. /*
  1153. * Setting upload_size causes
  1154. * transfer to happen in main loop
  1155. */
  1156. upload_size = size;
  1157. upload_bytes = 0;
  1158. upload_error = 0;
  1159. /*
  1160. * Poison the transfer buffer, 0xff
  1161. * is erase value of nand
  1162. */
  1163. memset(buf, 0xff, upload_size);
  1164. /* Which flavor of read to use */
  1165. if (is_raw)
  1166. sprintf(type, "read.raw");
  1167. else
  1168. sprintf(type, "read.i");
  1169. sprintf(addr, "0x%x",
  1170. interface.transfer_buffer);
  1171. sprintf(start, "0x%x", ptn->start);
  1172. sprintf(length, "0x%x", upload_size);
  1173. read[1] = type;
  1174. read[2] = addr;
  1175. read[3] = start;
  1176. read[4] = length;
  1177. set_ptn_ecc(ptn);
  1178. do_nand(NULL, 0, 5, read);
  1179. /* Send the data response */
  1180. sprintf(response, "DATA%08x", size);
  1181. }
  1182. }
  1183. #endif
  1184. ret = 0;
  1185. }
  1186. fastboot_tx_status(response, strlen(response));
  1187. } /* End of command */
  1188. return ret;
  1189. }
  1190. static int check_against_static_partition(struct fastboot_ptentry *ptn)
  1191. {
  1192. int ret = 0;
  1193. struct fastboot_ptentry *c;
  1194. int i;
  1195. for (i = 0; i < static_pcount; i++) {
  1196. c = fastboot_flash_get_ptn((unsigned int) i);
  1197. if (0 == ptn->length)
  1198. break;
  1199. if ((ptn->start >= c->start) &&
  1200. (ptn->start < c->start + c->length))
  1201. break;
  1202. if ((ptn->start + ptn->length > c->start) &&
  1203. (ptn->start + ptn->length <= c->start + c->length))
  1204. break;
  1205. if ((0 == strcmp(ptn->name, c->name)) &&
  1206. (0 == strcmp(c->name, ptn->name)))
  1207. break;
  1208. }
  1209. if (i >= static_pcount)
  1210. ret = 1;
  1211. return ret;
  1212. }
  1213. static unsigned long long memparse(char *ptr, char **retptr)
  1214. {
  1215. char *endptr; /* local pointer to end of parsed string */
  1216. unsigned long ret = simple_strtoul(ptr, &endptr, 0);
  1217. switch (*endptr) {
  1218. case 'M':
  1219. case 'm':
  1220. ret <<= 10;
  1221. case 'K':
  1222. case 'k':
  1223. ret <<= 10;
  1224. endptr++;
  1225. default:
  1226. break;
  1227. }
  1228. if (retptr)
  1229. *retptr = endptr;
  1230. return ret;
  1231. }
  1232. static int add_partition_from_environment(char *s, char **retptr)
  1233. {
  1234. unsigned long size;
  1235. unsigned long offset = 0;
  1236. char *name;
  1237. int name_len;
  1238. int delim;
  1239. unsigned int flags;
  1240. struct fastboot_ptentry part;
  1241. size = memparse(s, &s);
  1242. if (0 == size) {
  1243. printf("Error:FASTBOOT size of parition is 0\n");
  1244. return 1;
  1245. }
  1246. /* fetch partition name and flags */
  1247. flags = 0; /* this is going to be a regular partition */
  1248. delim = 0;
  1249. /* check for offset */
  1250. if (*s == '@') {
  1251. s++;
  1252. offset = memparse(s, &s);
  1253. } else {
  1254. printf("Error:FASTBOOT offset of parition is not given\n");
  1255. return 1;
  1256. }
  1257. /* now look for name */
  1258. if (*s == '(')
  1259. delim = ')';
  1260. if (delim) {
  1261. char *p;
  1262. name = ++s;
  1263. p = strchr((const char *)name, delim);
  1264. if (!p) {
  1265. printf("Error:FASTBOOT no closing %c found in partition name\n", delim);
  1266. return 1;
  1267. }
  1268. name_len = p - name;
  1269. s = p + 1;
  1270. } else {
  1271. printf("Error:FASTBOOT no partition name for \'%s\'\n", s);
  1272. return 1;
  1273. }
  1274. /* test for options */
  1275. while (1) {
  1276. if (strncmp(s, "i", 1) == 0) {
  1277. flags |= FASTBOOT_PTENTRY_FLAGS_WRITE_I;
  1278. s += 1;
  1279. } else if (strncmp(s, "yaffs", 5) == 0) {
  1280. /* yaffs */
  1281. flags |= FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS;
  1282. s += 5;
  1283. } else if (strncmp(s, "swecc", 5) == 0) {
  1284. /* swecc */
  1285. flags |= FASTBOOT_PTENTRY_FLAGS_WRITE_SW_ECC;
  1286. s += 5;
  1287. } else if (strncmp(s, "hwecc", 5) == 0) {
  1288. /* hwecc */
  1289. flags |= FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC;
  1290. s += 5;
  1291. } else {
  1292. break;
  1293. }
  1294. if (strncmp(s, "|", 1) == 0)
  1295. s += 1;
  1296. }
  1297. /* enter this partition (offset will be calculated later if it is zero at this point) */
  1298. part.length = size;
  1299. part.start = offset;
  1300. part.flags = flags;
  1301. if (name) {
  1302. if (name_len >= sizeof(part.name)) {
  1303. printf("Error:FASTBOOT partition name is too long\n");
  1304. return 1;
  1305. }
  1306. strncpy(&part.name[0], name, name_len);
  1307. /* name is not null terminated */
  1308. part.name[name_len] = '\0';
  1309. } else {
  1310. printf("Error:FASTBOOT no name\n");
  1311. return 1;
  1312. }
  1313. /* Check if this overlaps a static partition */
  1314. if (check_against_static_partition(&part)) {
  1315. printf("Adding: %s, offset 0x%8.8x, size 0x%8.8x, flags 0x%8.8x\n",
  1316. part.name, part.start, part.length, part.flags);
  1317. fastboot_flash_add_ptn(&part);
  1318. }
  1319. /* return (updated) pointer command line string */
  1320. *retptr = s;
  1321. /* return partition table */
  1322. return 0;
  1323. }
  1324. int do_fastboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  1325. {
  1326. int ret = 1;
  1327. char fbparts[4096], *env;
  1328. int check_timeout = 0;
  1329. uint64_t timeout_endtime = 0;
  1330. uint64_t timeout_ticks = 1000;
  1331. long timeout_seconds = -1;
  1332. int continue_from_disconnect = 0;
  1333. /*
  1334. * Place the runtime partitions at the end of the
  1335. * static paritions. First save the start off so
  1336. * it can be saved from run to run.
  1337. */
  1338. if (static_pcount >= 0) {
  1339. /* Reset */
  1340. pcount = static_pcount;
  1341. } else {
  1342. /* Save */
  1343. static_pcount = pcount;
  1344. }
  1345. env = getenv("fbparts");
  1346. if (env) {
  1347. unsigned int len;
  1348. len = strlen(env);
  1349. if (len && len < 4096) {
  1350. char *s, *e;
  1351. memcpy(&fbparts[0], env, len + 1);
  1352. printf("Fastboot: Adding partitions from environment\n");
  1353. s = &fbparts[0];
  1354. e = s + len;
  1355. while (s < e) {
  1356. if (add_partition_from_environment(s, &s)) {
  1357. printf("Error:Fastboot: Abort adding partitions\n");
  1358. /* reset back to static */
  1359. pcount = static_pcount;
  1360. break;
  1361. }
  1362. /* Skip a bunch of delimiters */
  1363. while (s < e) {
  1364. if ((' ' == *s) ||
  1365. ('\t' == *s) ||
  1366. ('\n' == *s) ||
  1367. ('\r' == *s) ||
  1368. (',' == *s)) {
  1369. s++;
  1370. } else {
  1371. break;
  1372. }
  1373. }
  1374. }
  1375. }
  1376. }
  1377. /* Time out */
  1378. if (2 == argc) {
  1379. long try_seconds;
  1380. char *try_seconds_end;
  1381. if (argv[1][0] == 'q') {
  1382. if ((argv[1][1] >= '0') && (argv[1][1] <= '2'))
  1383. fastboot_quick(argv[1][1] - '0');
  1384. else
  1385. fastboot_quick(0);
  1386. }
  1387. /* Check for timeout */
  1388. try_seconds = simple_strtol(argv[1],
  1389. &try_seconds_end, 10);
  1390. if ((try_seconds_end != argv[1]) &&
  1391. (try_seconds >= 0)) {
  1392. check_timeout = 1;
  1393. timeout_seconds = try_seconds;
  1394. printf("Fastboot inactivity timeout %ld seconds\n", timeout_seconds);
  1395. }
  1396. }
  1397. do {
  1398. continue_from_disconnect = 0;
  1399. /* Initialize the board specific support */
  1400. if (0 == fastboot_init(&interface)) {
  1401. int poll_status;
  1402. /* If we got this far, we are a success */
  1403. ret = 0;
  1404. printf("fastboot initialized\n");
  1405. timeout_endtime = get_timer(0);
  1406. timeout_endtime += timeout_ticks;
  1407. while (1) {
  1408. uint64_t current_time = 0;
  1409. poll_status = fastboot_poll();
  1410. if (1 == check_timeout)
  1411. current_time = get_timer(0);
  1412. if (FASTBOOT_ERROR == poll_status) {
  1413. /* Error */
  1414. break;
  1415. } else if (FASTBOOT_DISCONNECT == poll_status) {
  1416. /* beak, cleanup and re-init */
  1417. printf("Fastboot disconnect detected\n");
  1418. continue_from_disconnect = 1;
  1419. break;
  1420. } else if ((1 == check_timeout) &&
  1421. (FASTBOOT_INACTIVE == poll_status)) {
  1422. /* No activity */
  1423. if (current_time >= timeout_endtime) {
  1424. printf("Fastboot inactivity detected\n");
  1425. break;
  1426. }
  1427. } else {
  1428. /* Something happened */
  1429. if (1 == check_timeout) {
  1430. /* Update the timeout endtime */
  1431. timeout_endtime = current_time;
  1432. timeout_endtime += timeout_ticks;
  1433. }
  1434. }
  1435. /* Check if the user wanted to terminate with ^C */
  1436. if ((FASTBOOT_INACTIVE == poll_status) &&
  1437. (ctrlc())) {
  1438. printf("Fastboot ended by user\n");
  1439. break;
  1440. }
  1441. /*
  1442. * Check if the fastboot client wanted to
  1443. * continue booting
  1444. */
  1445. if (continue_booting) {
  1446. printf("Fastboot ended by client\n");
  1447. break;
  1448. }
  1449. /* Check if there is something to upload */
  1450. tx_handler();
  1451. }
  1452. }
  1453. /* Reset the board specific support */
  1454. fastboot_shutdown();
  1455. /* restart the loop if a disconnect was detected */
  1456. } while (continue_from_disconnect);
  1457. return ret;
  1458. }
  1459. U_BOOT_CMD(
  1460. fastboot, 2, 1, do_fastboot,
  1461. "fastboot- use USB Fastboot protocol\n",
  1462. "[inactive timeout]\n"
  1463. " - Run as a fastboot usb device.\n"
  1464. " - The optional inactive timeout is the decimal seconds before\n"
  1465. " - the normal console resumes\n"
  1466. );
  1467. /*
  1468. * Android style flash utilties */
  1469. void fastboot_flash_add_ptn(fastboot_ptentry *ptn)
  1470. {
  1471. if (pcount < MAX_PTN) {
  1472. memcpy(ptable + pcount, ptn, sizeof(fastboot_ptentry));
  1473. pcount++;
  1474. }
  1475. }
  1476. void fastboot_flash_dump_ptn(void)
  1477. {
  1478. unsigned int n;
  1479. for (n = 0; n < pcount; n++) {
  1480. fastboot_ptentry *ptn = ptable + n;
  1481. printf("ptn %d name='%s' start=%d len=%d\n",
  1482. n, ptn->name, ptn->start, ptn->length);
  1483. }
  1484. }
  1485. fastboot_ptentry *fastboot_flash_find_ptn(const char *name)
  1486. {
  1487. unsigned int n;
  1488. for (n = 0; n < pcount; n++) {
  1489. /* Make sure a substring is not accepted */
  1490. if (strlen(name) == strlen(ptable[n].name)) {
  1491. if (0 == strcmp(ptable[n].name, name))
  1492. return ptable + n;
  1493. }
  1494. }
  1495. printf("can't find partition: %s, dump the partition table\n", name);
  1496. fastboot_flash_dump_ptn();
  1497. return 0;
  1498. }
  1499. fastboot_ptentry *fastboot_flash_get_ptn(unsigned int n)
  1500. {
  1501. if (n < pcount)
  1502. return ptable + n;
  1503. else
  1504. return 0;
  1505. }
  1506. unsigned int fastboot_flash_get_ptn_count(void)
  1507. {
  1508. return pcount;
  1509. }
  1510. int fastboot_write_storage(u8 *partition_name, u32 write_len)
  1511. {
  1512. struct fastboot_ptentry *ptn;
  1513. u32 storage_len = 0;
  1514. if (0 == write_len) {
  1515. DBG_ERR("WriteMMC with 0 lenght\n");
  1516. return -1;
  1517. }
  1518. ptn = fastboot_flash_find_ptn((const char *)partition_name);
  1519. if (!ptn) {
  1520. DBG_ERR("Partition:'%s' does not exist\n", partition_name);
  1521. return -1;
  1522. }
  1523. if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV) {
  1524. DBG_ERR("ENV Write, None image partition, failed\n");
  1525. return -1;
  1526. }
  1527. DBG_DEBUG("PTN name=%s, start=0x%x, len=0x%x, flags=0x%x, id=0x%x\n",
  1528. ptn->name, ptn->start, ptn->length, ptn->flags, ptn->partition_id);
  1529. #if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  1530. storage_len = ptn->length;
  1531. #elif defined(CONFIG_FASTBOOT_STORAGE_EMMC_SATA)
  1532. storage_len = ptn->length * MMC_SATA_BLOCK_SIZE;
  1533. #endif
  1534. if (write_len > storage_len) {
  1535. DBG_ERR("Write len big than part volume. 0x%x:0x%x\n",
  1536. write_len, storage_len);
  1537. return -1;
  1538. }
  1539. #if defined(CONFIG_FASTBOOT_STORAGE_NAND)
  1540. DBG_ALWS("Writing nand %s...", ptn->name);
  1541. download_bytes_unpadded = download_bytes = write_len;
  1542. if (interface.nand_block_size) {
  1543. if (download_bytes %
  1544. interface.nand_block_size) {
  1545. unsigned int pad = interface.nand_block_size -
  1546. (download_bytes % interface.nand_block_size);
  1547. unsigned int i;
  1548. for (i = 0; i < pad; i++) {
  1549. if (download_bytes >=
  1550. interface.transfer_buffer_size)
  1551. break;
  1552. interface.transfer_buffer[download_bytes] = 0;
  1553. download_bytes++;
  1554. }
  1555. }
  1556. }
  1557. if (write_to_ptn(ptn)) {
  1558. DBG_ERR("Write to nand %s failed\n", ptn->name);
  1559. return -1;
  1560. } else {
  1561. DBG_ALWS("Write to nand %s done\n", ptn->name);
  1562. return write_len;
  1563. }
  1564. #elif defined(CONFIG_FASTBOOT_STORAGE_EMMC_SATA)
  1565. {
  1566. char source[32], dest[32], length[32];
  1567. char part_no[32], slot_no[32];
  1568. unsigned int temp;
  1569. char *mmc_write[5] = {"mmc", "write", source, dest, length};
  1570. char *mmc_dev[4] = {"mmc", "dev", slot_no, part_no};
  1571. memset(source, 0, sizeof(source));
  1572. memset(dest, 0, sizeof(dest));
  1573. memset(length, 0, sizeof(length));
  1574. memset(part_no, 0, sizeof(part_no));
  1575. memset(slot_no, 0, sizeof(slot_no));
  1576. sprintf(slot_no, "%d", fastboot_devinfo.dev_id);
  1577. sprintf(part_no, "%d", ptn->partition_id);
  1578. DBG_ALWS("Init MMC%s(%s)...\n", slot_no, ptn->name);
  1579. if(0) {
  1580. //if (do_mmcops(NULL, 0, 4, mmc_dev)) {
  1581. DBG_ERR("MMC%s(%s) init fail\n", slot_no, ptn->name);
  1582. return -1;
  1583. } else {
  1584. DBG_ALWS("MMC%s(%s) init done\n", slot_no, ptn->name);
  1585. }
  1586. sprintf(source, "0x%x", CONFIG_FASTBOOT_TRANSFER_BUF);
  1587. sprintf(dest, "0x%x", ptn->start);
  1588. temp = (write_len + MMC_SATA_BLOCK_SIZE - 1) / MMC_SATA_BLOCK_SIZE;
  1589. sprintf(length, "0x%x", temp);
  1590. DBG_ALWS("Writing MMC%s(%s), %u blocks...", slot_no, ptn->name, temp);
  1591. if(0) {
  1592. //if (do_mmcops(NULL, 0, 5, mmc_write)) {
  1593. DBG_ERR("MMC%s(%s) write fail\n", slot_no, ptn->name);
  1594. return -1;
  1595. } else {
  1596. DBG_ALWS("MMC%s(%s) write done\n", slot_no, ptn->name);
  1597. return write_len;
  1598. }
  1599. }
  1600. #endif
  1601. }
  1602. #endif /* CONFIG_FASTBOOT */