fastboot.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  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 <debug.h>
  32. #include <err.h>
  33. #include <string.h>
  34. #include <stdlib.h>
  35. #include <kernel/thread.h>
  36. #include <kernel/timer.h>
  37. #include <kernel/event.h>
  38. #include <dev/udc.h>
  39. #include <platform/mt_typedefs.h>
  40. #include <platform/mtk_wdt.h>
  41. #include <version.h>
  42. #include <verified_boot_common.h> // for sec_query_warranty()
  43. #include "sys_commands.h"
  44. #include <block_generic_interface.h>
  45. #include <part_interface.h>
  46. #include <pal_log.h>
  47. #ifdef MTK_AB_OTA_UPDATER
  48. #include <bootctrl.h>
  49. #endif // MTK_AB_OTA_UPDATER
  50. extern int get_off_mode_charge_status(void); // FIXME!!! #include <xxx.h> // for get_off_mode_charge_status()
  51. #include "dl_commands.h"
  52. #include "fastboot.h"
  53. #ifdef MTK_GPT_SCHEME_SUPPORT
  54. #include <platform/partition.h>
  55. #else
  56. #include <mt_partition.h>
  57. #endif
  58. #if defined(MTK_SECURITY_SW_SUPPORT) && defined(MTK_SEC_FASTBOOT_UNLOCK_SUPPORT)
  59. #include "sec_unlock.h"
  60. #endif
  61. #include <platform/boot_mode.h>
  62. #ifdef FASTBOOT_WHOLE_FLASH_SUPPORT
  63. #include "partition_parser.h"
  64. #endif
  65. #define MAX_RSP_SIZE 64
  66. /* MAX_USBFS_BULK_SIZE: if use USB3 QMU GPD mode: cannot exceed 63 * 1024 */
  67. #define MAX_USBFS_BULK_SIZE (16 * 1024)
  68. #define EXPAND(NAME) #NAME
  69. #define TARGET(NAME) EXPAND(NAME)
  70. #define USB_CMD_TIMEOUT 5000
  71. static event_t usb_online;
  72. static event_t txn_done;
  73. static unsigned char buffer[4096] __attribute__((aligned(64)));
  74. static char response[MAX_RSP_SIZE] __attribute__((aligned(64)));
  75. static struct udc_endpoint *in, *out;
  76. static struct udc_request *req;
  77. int txn_status;
  78. void *download_base;
  79. unsigned download_max;
  80. unsigned download_size;
  81. extern int sec_usbdl_enabled (void);
  82. extern void mtk_wdt_disable(void);
  83. extern void mtk_wdt_restart(void);
  84. extern unsigned get_secure_status(void);
  85. extern unsigned get_unlocked_status(void);
  86. unsigned fastboot_state = STATE_OFFLINE;
  87. extern void fastboot_oem_key(const char *arg, void *data, unsigned sz);
  88. extern void fastboot_oem_query_lock_state(const char *arg, void *data, unsigned sz);
  89. timer_t wdt_timer;
  90. struct fastboot_cmd *cmdlist;
  91. extern BOOT_ARGUMENT *g_boot_arg;
  92. extern char sn_buf[];
  93. extern int get_bat_volt(int times);
  94. char battery_voltage[6] = "";
  95. char hw_revision[12] = "";
  96. char erase_blk_size[12] = "";
  97. char logical_blk_size[12] = "";
  98. #define RADIO_VER_LEN 64
  99. char radio_version[RADIO_VER_LEN+1];
  100. int modem_image_loaded = 0;
  101. extern void ccci_load_modem_image(void);
  102. extern int ccci_get_md_version(int md_id, char buf[], int size);
  103. static void req_complete(struct udc_request *req, unsigned actual, int status)
  104. {
  105. txn_status = status;
  106. req->length = actual;
  107. event_signal(&txn_done, 0);
  108. }
  109. void update_device_info()
  110. {
  111. sprintf(battery_voltage, "%dmV", get_bat_volt(1));
  112. sprintf(hw_revision, "%x", mt_get_chip_hw_ver());
  113. #ifndef MNTL_SUPPORT
  114. sprintf(erase_blk_size, "0x%lx", mt_part_get_erasesz());
  115. sprintf(logical_blk_size, "0x%lx", mt_part_get_blksz());
  116. #endif
  117. }
  118. void update_radio_version()
  119. {
  120. int len = 0;
  121. #ifdef LK_LD_MD_SUPPORT
  122. dprintf(INFO, "load modem image in fastboot mode to get radio version\n");
  123. ccci_load_modem_image();
  124. modem_image_loaded = 1;
  125. len = ccci_get_md_version(0, radio_version, RADIO_VER_LEN);
  126. #endif
  127. if (len <= 0)
  128. sprintf(radio_version, "N/A");
  129. }
  130. void fastboot_register(const char *prefix, void (*handle)(const char *arg, void *data, unsigned sz),
  131. unsigned allowed_when_security_on, unsigned forbidden_when_lock_on)
  132. {
  133. struct fastboot_cmd *cmd;
  134. cmd = malloc(sizeof(*cmd));
  135. if (cmd) {
  136. cmd->prefix = prefix;
  137. cmd->prefix_len = strlen(prefix);
  138. cmd->allowed_when_security_on = allowed_when_security_on;
  139. cmd->forbidden_when_lock_on = forbidden_when_lock_on;
  140. cmd->handle = handle;
  141. cmd->next = cmdlist;
  142. cmdlist = cmd;
  143. }
  144. }
  145. struct fastboot_var *varlist;
  146. void fastboot_publish(const char *name, const char *value)
  147. {
  148. struct fastboot_var *var;
  149. var = malloc(sizeof(*var));
  150. if (var) {
  151. var->name = name;
  152. var->value = value;
  153. var->next = varlist;
  154. varlist = var;
  155. }
  156. }
  157. void fastboot_update_var(const char *name, const char *value)
  158. {
  159. struct fastboot_var *var = varlist;
  160. while (NULL != var) {
  161. if (!strcmp(name, var->name)) {
  162. var->value = value;
  163. }
  164. var = var->next;
  165. }
  166. return;
  167. }
  168. const char *fastboot_get_var(const char *name)
  169. {
  170. struct fastboot_var *var = varlist;
  171. while (NULL != var) {
  172. if (!strcmp(name, var->name)) {
  173. return var->value;
  174. }
  175. var = var->next;
  176. }
  177. return "";
  178. }
  179. int usb_read(void *_buf, unsigned len)
  180. {
  181. int r;
  182. unsigned xfer;
  183. unsigned char *buf = _buf;
  184. int count = 0;
  185. if (fastboot_state == STATE_ERROR)
  186. goto oops;
  187. while (len > 0) {
  188. xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len;
  189. req->buf = buf;
  190. req->length = xfer;
  191. req->complete = req_complete;
  192. r = udc_request_queue(out, req);
  193. if (r < 0) {
  194. dprintf(INFO, "usb_read() queue failed\n");
  195. goto oops;
  196. }
  197. event_wait(&txn_done);
  198. if (txn_status < 0) {
  199. dprintf(INFO, "usb_read() transaction failed\n");
  200. goto oops;
  201. }
  202. count += req->length;
  203. buf += req->length;
  204. len -= req->length;
  205. /* short transfer? */
  206. if (req->length != xfer) break;
  207. }
  208. return count;
  209. oops:
  210. fastboot_state = STATE_ERROR;
  211. return -1;
  212. }
  213. int usb_read_with_timeout(void *_buf, unsigned len, time_t timeout)
  214. {
  215. int r;
  216. unsigned xfer;
  217. unsigned char *buf = _buf;
  218. int count = 0;
  219. status_t ret = NO_ERROR;
  220. if (fastboot_state == STATE_ERROR)
  221. goto oops;
  222. while (len > 0) {
  223. xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len;
  224. req->buf = buf;
  225. req->length = xfer;
  226. req->complete = req_complete;
  227. r = udc_request_queue(out, req);
  228. if (r < 0) {
  229. dprintf(INFO, "usb_read() queue failed\n");
  230. goto oops;
  231. }
  232. ret = event_wait_timeout(&txn_done, timeout);
  233. if (ret != NO_ERROR) {
  234. goto oops;
  235. }
  236. if (txn_status < 0) {
  237. dprintf(INFO, "usb_read() transaction failed\n");
  238. goto oops;
  239. }
  240. count += req->length;
  241. buf += req->length;
  242. len -= req->length;
  243. /* short transfer? */
  244. if (req->length != xfer) break;
  245. }
  246. return count;
  247. oops:
  248. fastboot_state = STATE_ERROR;
  249. return -1;
  250. }
  251. int usb_write(void *buf, unsigned len)
  252. {
  253. int r;
  254. if (fastboot_state == STATE_ERROR)
  255. goto oops;
  256. req->buf = buf;
  257. req->length = len;
  258. req->complete = req_complete;
  259. r = udc_request_queue(in, req);
  260. if (r < 0) {
  261. dprintf(INFO, "usb_write() queue failed\n");
  262. goto oops;
  263. }
  264. event_wait(&txn_done);
  265. if (txn_status < 0) {
  266. dprintf(INFO, "usb_write() transaction failed\n");
  267. goto oops;
  268. }
  269. return req->length;
  270. oops:
  271. fastboot_state = STATE_ERROR;
  272. return -1;
  273. }
  274. int usb_write_with_timeout(void *buf, unsigned len, time_t timeout)
  275. {
  276. int r;
  277. status_t ret = NO_ERROR;
  278. if (fastboot_state == STATE_ERROR)
  279. goto oops;
  280. req->buf = buf;
  281. req->length = len;
  282. req->complete = req_complete;
  283. r = udc_request_queue(in, req);
  284. if (r < 0) {
  285. dprintf(INFO, "usb_write() queue failed\n");
  286. goto oops;
  287. }
  288. ret = event_wait_timeout(&txn_done, timeout);
  289. if (ret != NO_ERROR) {
  290. goto oops;
  291. }
  292. if (txn_status < 0) {
  293. dprintf(INFO, "usb_write() transaction failed\n");
  294. goto oops;
  295. }
  296. return req->length;
  297. oops:
  298. fastboot_state = STATE_ERROR;
  299. return -1;
  300. }
  301. void fastboot_ack(const char *code, const char *reason)
  302. {
  303. if (fastboot_state != STATE_COMMAND)
  304. return;
  305. if (reason == 0)
  306. reason = "";
  307. memset(response, 0, sizeof(response));
  308. snprintf(response, MAX_RSP_SIZE, "%s%s", code, reason);
  309. fastboot_state = STATE_COMPLETE;
  310. usb_write_with_timeout(response, strlen(response), USB_CMD_TIMEOUT);
  311. }
  312. void fastboot_info(const char *reason)
  313. {
  314. if (fastboot_state != STATE_COMMAND)
  315. return;
  316. if (reason == 0)
  317. return;
  318. memset(response, 0, sizeof(response));
  319. snprintf(response, MAX_RSP_SIZE, "INFO%s", reason);
  320. usb_write_with_timeout(response, strlen(response), USB_CMD_TIMEOUT);
  321. }
  322. void fastboot_fail(const char *reason)
  323. {
  324. fastboot_ack("FAIL", reason);
  325. }
  326. void fastboot_okay(const char *info)
  327. {
  328. fastboot_ack("OKAY", info);
  329. }
  330. static void fastboot_command_loop(void)
  331. {
  332. struct fastboot_cmd *cmd;
  333. int r;
  334. dprintf(ALWAYS,"fastboot: processing commands\n");
  335. again:
  336. while (fastboot_state != STATE_ERROR) {
  337. memset(buffer, 0, sizeof(buffer));
  338. r = usb_read(buffer, MAX_RSP_SIZE);
  339. if (r < 0) break; //no input command
  340. buffer[r] = 0;
  341. dprintf(ALWAYS,"[fastboot: command buf]-[%s]-[len=%d]\n", buffer, r);
  342. dprintf(ALWAYS,"[fastboot]-[download_base:0x%x]-[download_size:0x%x]\n",(unsigned int)download_base,(unsigned int)download_size);
  343. /*Pick up matched command and handle it*/
  344. for (cmd = cmdlist; cmd; cmd = cmd->next) {
  345. fastboot_state = STATE_COMMAND;
  346. if (memcmp(buffer, cmd->prefix, cmd->prefix_len)) {
  347. continue;
  348. }
  349. dprintf(ALWAYS,"[Cmd process]-[buf:%s]-[lenBuf:%s]\n", buffer, buffer + cmd->prefix_len);
  350. #ifdef MTK_SECURITY_SW_SUPPORT
  351. extern unsigned int seclib_sec_boot_enabled(unsigned int);
  352. //if security boot enable, check cmd allowed
  353. if ( !(sec_usbdl_enabled() || seclib_sec_boot_enabled(1)) || cmd->allowed_when_security_on )
  354. if ((!cmd->forbidden_when_lock_on) || (0 != get_unlocked_status()))
  355. #endif
  356. {
  357. cmd->handle((const char*) buffer + cmd->prefix_len, (void*) download_base, download_size);
  358. }
  359. if (fastboot_state == STATE_COMMAND) {
  360. #ifdef MTK_SECURITY_SW_SUPPORT
  361. if ((sec_usbdl_enabled() || seclib_sec_boot_enabled(1)) && !cmd->allowed_when_security_on ) {
  362. fastboot_fail("not support on security");
  363. } else if ((cmd->forbidden_when_lock_on) && (0 == get_unlocked_status())) {
  364. fastboot_fail("not allowed in locked state");
  365. } else
  366. #endif
  367. {
  368. fastboot_fail("unknown reason");
  369. }
  370. }
  371. goto again;
  372. }
  373. dprintf(ALWAYS,"[unknown command]*[%s]*\n", buffer);
  374. fastboot_fail("unknown command");
  375. }
  376. fastboot_state = STATE_OFFLINE;
  377. dprintf(ALWAYS,"fastboot: oops!\n");
  378. }
  379. static int fastboot_handler(void *arg)
  380. {
  381. for (;;) {
  382. event_wait(&usb_online);
  383. fastboot_command_loop();
  384. }
  385. return 0;
  386. }
  387. static void fastboot_notify(struct udc_gadget *gadget, unsigned event)
  388. {
  389. if (event == UDC_EVENT_ONLINE) {
  390. event_signal(&usb_online, 0);
  391. } else if (event == UDC_EVENT_OFFLINE) {
  392. event_unsignal(&usb_online);
  393. }
  394. }
  395. static struct udc_endpoint *fastboot_endpoints[2];
  396. static struct udc_gadget fastboot_gadget = {
  397. .notify = fastboot_notify,
  398. .ifc_class = 0xff,
  399. .ifc_subclass = 0x42,
  400. .ifc_protocol = 0x03,
  401. .ifc_endpoints = 2,
  402. .ifc_string = "fastboot",
  403. .ept = fastboot_endpoints,
  404. };
  405. extern void fastboot_oem_register();
  406. void register_partition_var(void)
  407. {
  408. int i, buf_len, val_buf_len = 20;
  409. unsigned long long p_size;
  410. char part_type[] = "partition-type:";
  411. char part_size[] = "partition-size:";
  412. char *type_buf;
  413. char *value_buf;
  414. char *var_name_buf;
  415. char *p_name_buf;
  416. for (i=0; i<PART_MAX_COUNT; i++) {
  417. p_size = partition_get_size(i);
  418. if ((long long)p_size == -1)
  419. continue;
  420. partition_get_name(i,&p_name_buf);
  421. partition_get_type(i,&type_buf);
  422. buf_len = strlen(part_type) + strlen(p_name_buf)+1;
  423. var_name_buf = malloc(buf_len);
  424. if (!var_name_buf) {
  425. pal_log_info("var_name_buf malloc fails. partition:%s len:%d\n", p_name_buf, buf_len);
  426. continue;
  427. }
  428. snprintf(var_name_buf, buf_len, "%s%s", part_type, p_name_buf);
  429. fastboot_publish(var_name_buf,type_buf);
  430. //printf("%d %s %s\n",i,var_name_buf,type_buf);
  431. /*reserved for MTK security*/
  432. if (!strcmp(type_buf,"ext4")) {
  433. if (!strcmp(p_name_buf,"userdata")) {
  434. p_size -= (u64)1*1024*1024;
  435. }
  436. }
  437. value_buf = malloc(val_buf_len);
  438. if (!value_buf) {
  439. pal_log_info("value_buf malloc fails. partition:%s len:%d\n", p_name_buf, val_buf_len);
  440. continue;
  441. }
  442. snprintf(value_buf,val_buf_len,"%llx",p_size);
  443. buf_len = strlen(part_size) + strlen(p_name_buf)+1;
  444. var_name_buf = malloc(buf_len);
  445. if (!var_name_buf) {
  446. pal_log_info("var_name_buf malloc fails. partition:%s len:%d\n", p_name_buf, buf_len);
  447. continue;
  448. }
  449. snprintf(var_name_buf, buf_len, "%s%s", part_size, p_name_buf);
  450. fastboot_publish(var_name_buf,value_buf);
  451. //printf("%d %s %s\n",i,var_name_buf,value_buf);
  452. }
  453. }
  454. /* return value: 1: option is valid, 0: option is invalid */
  455. static unsigned int is_option_valid(unsigned int lower, unsigned int upper, unsigned int option)
  456. {
  457. if (option < lower)
  458. return 0;
  459. if (option > upper)
  460. return 0;
  461. return 1;
  462. }
  463. #define NUM_SEC_OPTION (2)
  464. static void register_secure_unlocked_var(void)
  465. {
  466. static const char str_buf[NUM_SEC_OPTION][4] = {"no","yes"};
  467. unsigned secure_status = 0; /* default value is "no" */
  468. unsigned unlocked_status = 1; /* default value is "yes" */
  469. int warranty = 0; /* default value is "no" */
  470. #ifdef MTK_SECURITY_SW_SUPPORT
  471. secure_status = get_secure_status();
  472. /* use default value if result is out or range */
  473. if (secure_status >= NUM_SEC_OPTION)
  474. secure_status = 0;
  475. /* use default value if result is out or range */
  476. unlocked_status = get_unlocked_status();
  477. if (unlocked_status >= NUM_SEC_OPTION)
  478. unlocked_status = 1;
  479. sec_query_warranty(&warranty);
  480. if (warranty >= NUM_SEC_OPTION)
  481. warranty = 0;
  482. #endif
  483. if (is_option_valid(0, NUM_SEC_OPTION - 1, secure_status))
  484. fastboot_publish("secure", str_buf[secure_status]);
  485. if (is_option_valid(0, NUM_SEC_OPTION - 1, unlocked_status))
  486. fastboot_publish("unlocked", str_buf[unlocked_status]);
  487. if (is_option_valid(0, NUM_SEC_OPTION - 1, (unsigned int)warranty))
  488. fastboot_publish("warranty", str_buf[warranty]);
  489. return;
  490. }
  491. #ifdef MTK_OFF_MODE_CHARGE_SUPPORT
  492. static void register_off_mode_charge_var(void)
  493. {
  494. //INIT VALUE
  495. static const char str_buf[2][2] = {"0", "1"};
  496. unsigned off_mode_status = 0; /* default value is "0" */
  497. off_mode_status = get_off_mode_charge_status();
  498. if ((off_mode_status == 0) || (off_mode_status == 1))
  499. fastboot_publish("off-mode-charge", str_buf[off_mode_status]);
  500. else
  501. dprintf(INFO, "off mode charge status is out of boundary\n");
  502. }
  503. #endif
  504. #ifdef MTK_AB_OTA_UPDATER
  505. /******************************************************************************
  506. ******************************************************************************/
  507. static char *part_name_array[PART_MAX_COUNT] = {NULL};
  508. static int part_name_index = 0;
  509. /******************************************************************************
  510. ******************************************************************************/
  511. static bool is_part_name_processed(char *name)
  512. {
  513. for (int i = 0; i < PART_MAX_COUNT; i++) {
  514. if (!part_name_array[i]) {
  515. return false;
  516. }
  517. int len = strlen(name);
  518. if (!strncmp(part_name_array[i], name, len + 1))
  519. return true;
  520. else
  521. continue;
  522. }
  523. return false;
  524. }
  525. /******************************************************************************
  526. ******************************************************************************/
  527. static void insert_part_name(char *name)
  528. {
  529. if (part_name_index >= PART_MAX_COUNT)
  530. return false;
  531. part_name_array[part_name_index] = name;
  532. part_name_index++;
  533. return true;
  534. }
  535. /******************************************************************************
  536. ******************************************************************************/
  537. static void release_part_name(void)
  538. {
  539. for (int i = 0; i < part_name_index; i++) {
  540. free(part_name_array[i]);
  541. part_name_array[i] = NULL;
  542. }
  543. }
  544. /******************************************************************************
  545. * This function publishes the following variables: "has-slot", "current-slot",
  546. * "slot-count", "slot-successful", "slot-unbootable", and "slot-retry-count".
  547. *
  548. * Note: The "preloader" partition is the only exception that does not have
  549. * "_a" or "_b" suffix even when it supports A/B systems.
  550. ******************************************************************************/
  551. static void publish_ab_variables(void)
  552. {
  553. char *str_yes = "yes";
  554. char *str_no = "no";
  555. char *str_yes_or_no = NULL;
  556. char *str_slot_count = "2";
  557. char *str_has_slot = "has-slot:";
  558. const int has_slot_len = strlen(str_has_slot);
  559. char *str_successful_a = "slot-successful:a";
  560. char *str_successful_b = "slot-successful:b";
  561. char *str_unbootable_a = "slot-unbootable:a";
  562. char *str_unbootable_b = "slot-unbootable:b";
  563. char *str_retry_a = "slot-retry-count:a";
  564. char *str_retry_b = "slot-retry-count:b";
  565. static char str_retry_count_a[4] = {'\0'};
  566. static char str_retry_count_b[4] = {'\0'};
  567. char *str_preloader = "has-slot:preloader";
  568. char *ab_suffix = NULL;
  569. for (int i = 0; i < PART_MAX_COUNT; i++) {
  570. char *part_name;
  571. int ret = partition_get_name(i, &part_name);
  572. if (ret < 0)
  573. break; // early termination
  574. int len = has_slot_len + strlen(part_name) + 1; // include NULL
  575. char *new_name = malloc(len);
  576. if (!new_name) {
  577. release_part_name();
  578. dprintf(CRITICAL, "%s (L%d) Error: failed to allocate memory!\n",
  579. __func__, __LINE__);
  580. return;
  581. }
  582. snprintf(new_name, len, "%s%s", str_has_slot, part_name);
  583. if (new_name[len - 3] == '_') {
  584. if (new_name[len - 2] == 'a' || new_name[len - 2] == 'b') {
  585. str_yes_or_no = str_yes;
  586. new_name[len - 3] = '\0'; // truncate suffix
  587. }
  588. } else {
  589. /* Preloader is the only exception that does not have A/B suffix. */
  590. if (!strncmp(new_name, str_preloader, strlen(str_preloader))) {
  591. if (get_suffix() != NULL)
  592. str_yes_or_no = str_yes;
  593. } else
  594. str_yes_or_no = str_no;
  595. }
  596. if (!is_part_name_processed(new_name)) {
  597. insert_part_name(new_name);
  598. fastboot_publish(new_name, str_yes_or_no);
  599. }
  600. }
  601. /* current-slot */
  602. ab_suffix = get_suffix();
  603. if(!strncmp(ab_suffix, "_", 1)) //remove the under line
  604. ab_suffix = ab_suffix+1;
  605. fastboot_publish("current-slot", ab_suffix);
  606. /* slot-count */
  607. fastboot_publish("slot-count", str_slot_count);
  608. int result;
  609. /* slot-successful */
  610. /* get_bootup_status() returns 1 for successful boot. Otherwise, return 0. */
  611. result = get_bootup_status("_a");
  612. if (result)
  613. str_yes_or_no = str_yes;
  614. else
  615. str_yes_or_no = str_no;
  616. fastboot_publish(str_successful_a, str_yes_or_no);
  617. result = get_bootup_status("_b");
  618. if (result)
  619. str_yes_or_no = str_yes;
  620. else
  621. str_yes_or_no = str_no;
  622. fastboot_publish(str_successful_b, str_yes_or_no);
  623. /* slot-unbootable */
  624. /* get_bootable_status() returns -1 for unbootable. Otherwise, return 0. */
  625. result = get_bootable_status("_a");
  626. if (result <= 0)
  627. str_yes_or_no = str_yes;
  628. else
  629. str_yes_or_no = str_no;
  630. fastboot_publish(str_unbootable_a, str_yes_or_no);
  631. result = get_bootable_status("_b");
  632. if (result <= 0)
  633. str_yes_or_no = str_yes;
  634. else
  635. str_yes_or_no = str_no;
  636. fastboot_publish(str_unbootable_b, str_yes_or_no);
  637. /* slot-retry-count */
  638. uint8_t retry_count = get_retry_count("_a");
  639. snprintf(str_retry_count_a, sizeof(str_retry_count_a), "%d", (int)retry_count);
  640. fastboot_publish(str_retry_a, str_retry_count_a);
  641. retry_count = get_retry_count("_b");
  642. snprintf(str_retry_count_b, sizeof(str_retry_count_b), "%d", (int)retry_count);
  643. fastboot_publish(str_retry_b, str_retry_count_b);
  644. // release_part_name(); // Do NOT release string here!
  645. }
  646. #else
  647. static void publish_ab_variables(void)
  648. {
  649. /* slot-count, return 0 for non A/B system */
  650. fastboot_publish("slot-count", "0");
  651. }
  652. #endif // MTK_AB_OTA_UPDATER
  653. /******************************************************************************
  654. ******************************************************************************/
  655. int fastboot_init(void *base, unsigned size)
  656. {
  657. thread_t *thr;
  658. int ret;
  659. static char dl_max_str[11]; // Take NULL and leading 0x into account. SCRATCH_SIZE must be <= 32-bits
  660. dprintf(ALWAYS, "fastboot_init()\n");
  661. download_base = base;
  662. download_max = SCRATCH_SIZE;
  663. snprintf(dl_max_str, sizeof(dl_max_str), "0x%X", download_max);
  664. //mtk_wdt_disable(); /*It will re-enable during continue boot*/
  665. timer_initialize(&wdt_timer);
  666. timer_set_periodic(&wdt_timer, 5000, (timer_callback)mtk_wdt_restart, NULL);
  667. fastboot_register("getvar:", cmd_getvar, TRUE, FALSE);
  668. fastboot_publish("version", "0.5");
  669. fastboot_publish("version-preloader", g_boot_arg->pl_version);
  670. fastboot_publish("version-bootloader", LK_VER_TAG);
  671. update_radio_version();
  672. fastboot_publish("version-baseband", (const char *)radio_version);
  673. publish_ab_variables();
  674. fastboot_publish("is-userspace", "no");
  675. fastboot_register("signature", cmd_install_sig, FALSE, TRUE);
  676. #if (defined(MTK_EMMC_SUPPORT) || defined(MTK_UFS_SUPPORT)) && defined(MTK_SPI_NOR_SUPPORT)
  677. dprintf(ALWAYS,"Init EMMC device in fastboot mode\n");
  678. mmc_legacy_init(1);
  679. #endif
  680. fastboot_register("flash:", cmd_flash_mmc, TRUE, TRUE);
  681. fastboot_register("erase:", cmd_erase_mmc, TRUE, TRUE);
  682. fastboot_register("oem printk-ratelimit", cmd_printk_ratelimit, TRUE, FALSE);
  683. fastboot_register("continue", cmd_continue, FALSE, FALSE);
  684. fastboot_register("reboot", cmd_reboot, TRUE, FALSE);
  685. fastboot_register("reboot-bootloader", cmd_reboot_bootloader, TRUE, FALSE);
  686. fastboot_register("reboot-recovery",cmd_reboot_recovery, TRUE, FALSE);
  687. fastboot_register("reboot-fastboot",cmd_reboot_fastboot, TRUE, FALSE);
  688. fastboot_publish("product", PROJECT);
  689. fastboot_publish("kernel", "lk");
  690. register_secure_unlocked_var();
  691. #ifdef MTK_OFF_MODE_CHARGE_SUPPORT
  692. register_off_mode_charge_var();
  693. #endif
  694. fastboot_publish("serialno", sn_buf);
  695. register_partition_var();
  696. update_device_info();
  697. fastboot_publish("battery-voltage", (const char *) battery_voltage);
  698. fastboot_publish("battery-soc-ok", "yes");
  699. fastboot_publish("hw-revision", (const char *) hw_revision);
  700. fastboot_publish("erase-block-size", erase_blk_size); //temp. hard code for Zion, 512K bytes
  701. fastboot_publish("logical-block-size", logical_blk_size); //temp. hard code for Zion, 512 bytes
  702. fastboot_publish("variant", ""); //empty if no variants exist
  703. /*LXO: Download related command*/
  704. fastboot_register("download:", cmd_download, TRUE, FALSE);
  705. fastboot_publish("max-download-size", dl_max_str);
  706. /*LXO: END!Download related command*/
  707. fastboot_oem_register();
  708. #if defined(MTK_SECURITY_SW_SUPPORT)
  709. fastboot_register("oem p2u", cmd_oem_p2u, TRUE, FALSE);
  710. #endif
  711. #ifdef FASTBOOT_DUMP_LOG
  712. fastboot_register("oem dump_pllk_log", cmd_oem_dump_log, TRUE, FALSE);
  713. #endif
  714. #ifdef MTK_OFF_MODE_CHARGE_SUPPORT
  715. fastboot_register("oem off-mode-charge",cmd_oem_off_mode_charge,FALSE, FALSE);
  716. #endif
  717. #if defined(MTK_SECURITY_SW_SUPPORT) && defined(MTK_SEC_FASTBOOT_UNLOCK_SUPPORT)
  718. fastboot_register("oem key",fastboot_oem_key,TRUE, FALSE);
  719. fastboot_register("oem lks",fastboot_oem_query_lock_state,TRUE, FALSE);
  720. /* allowed when secure boot and unlocked */
  721. fastboot_register("boot", cmd_boot, TRUE, TRUE);
  722. /* command rename */
  723. fastboot_register("flashing unlock",fastboot_oem_unlock, TRUE, FALSE);
  724. fastboot_register("flashing lock",fastboot_oem_lock, TRUE, FALSE);
  725. fastboot_register("flashing get_unlock_ability", fastboot_get_unlock_ability, TRUE, FALSE);
  726. #endif
  727. fastboot_register("oem get_socid", fastboot_get_socid, TRUE, FALSE);
  728. #ifdef MTK_JTAG_SWITCH_SUPPORT
  729. /* pin mux switch to ap_jtag */
  730. fastboot_register("oem ap_jtag",cmd_oem_ap_jtag, TRUE, FALSE);
  731. #endif
  732. #ifdef MTK_TINYSYS_SCP_SUPPORT
  733. fastboot_register("oem scp_status", cmd_oem_scp_status, TRUE, FALSE);
  734. fastboot_register("oem scp_log_thru_ap_uart", cmd_oem_scp_log_thru_ap_uart, TRUE, FALSE);
  735. #endif
  736. #ifdef MTK_USB2JTAG_SUPPORT
  737. fastboot_register("oem usb2jtag", cmd_oem_usb2jtag, TRUE, FALSE);
  738. #endif
  739. #ifdef MTK_MRDUMP_SUPPORT
  740. fastboot_register("oem mrdump", cmd_oem_mrdump, TRUE, FALSE);
  741. fastboot_register("oem mrdump-output-set",
  742. cmd_oem_mrdump_outdev, TRUE, FALSE);
  743. fastboot_register("oem mrdump-file-allocate",
  744. cmd_oem_mrdump_fallocate, TRUE, FALSE);
  745. fastboot_register("oem mrdump_chkimg",
  746. cmd_oem_mrdump_chkimg, TRUE, FALSE);
  747. #endif
  748. #ifdef MTK_AB_OTA_UPDATER
  749. fastboot_register("set_active:", cmd_set_active, TRUE, FALSE);
  750. #endif
  751. #ifdef MTK_ULTRA_FLASH
  752. fastboot_register("oem ultraflash:", cmd_oem_ultra_flash, TRUE, TRUE);
  753. fastboot_register("oem ultraflash_en", cmd_oem_ultra_flash_en, TRUE, TRUE);
  754. fastboot_register("ultraflash:", cmd_oem_ultra_flash, TRUE, TRUE);
  755. #endif
  756. event_init(&usb_online, 0, EVENT_FLAG_AUTOUNSIGNAL);
  757. event_init(&txn_done, 0, EVENT_FLAG_AUTOUNSIGNAL);
  758. in = udc_endpoint_alloc(UDC_TYPE_BULK_IN, 512);
  759. if (!in) {
  760. ret = -1;
  761. goto fail_alloc_in;
  762. }
  763. out = udc_endpoint_alloc(UDC_TYPE_BULK_OUT, 512);
  764. if (!out) {
  765. ret = -2;
  766. goto fail_alloc_out;
  767. }
  768. fastboot_endpoints[0] = in;
  769. fastboot_endpoints[1] = out;
  770. req = udc_request_alloc();
  771. if (!req) {
  772. ret = -3;
  773. goto fail_alloc_req;
  774. }
  775. if (udc_register_gadget(&fastboot_gadget)) {
  776. ret = -4;
  777. goto fail_udc_register;
  778. }
  779. thr = thread_create("fastboot", fastboot_handler, 0, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
  780. if (!thr) {
  781. ret = -1;
  782. goto fail_alloc_in;
  783. }
  784. thread_resume(thr);
  785. return 0;
  786. fail_udc_register:
  787. udc_request_free(req);
  788. fail_alloc_req:
  789. udc_endpoint_free(out);
  790. fail_alloc_out:
  791. udc_endpoint_free(in);
  792. fail_alloc_in:
  793. dprintf(CRITICAL, "%s fail: %d\n", __func__, ret);
  794. ASSERT(0);
  795. return ret;
  796. }