fastboot.c 28 KB

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