fb_common.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2008 - 2009
  4. * Windriver, <www.windriver.com>
  5. * Tom Rix <Tom.Rix@windriver.com>
  6. *
  7. * Copyright 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de>
  8. *
  9. * Copyright 2014 Linaro, Ltd.
  10. * Rob Herring <robh@kernel.org>
  11. */
  12. #include <bcb.h>
  13. #include <common.h>
  14. #include <command.h>
  15. #include <env.h>
  16. #include <fastboot.h>
  17. #include <net/fastboot.h>
  18. /**
  19. * fastboot_buf_addr - base address of the fastboot download buffer
  20. */
  21. void *fastboot_buf_addr;
  22. /**
  23. * fastboot_buf_size - size of the fastboot download buffer
  24. */
  25. u32 fastboot_buf_size;
  26. /**
  27. * fastboot_progress_callback - callback executed during long operations
  28. */
  29. void (*fastboot_progress_callback)(const char *msg);
  30. /**
  31. * fastboot_response() - Writes a response of the form "$tag$reason".
  32. *
  33. * @tag: The first part of the response
  34. * @response: Pointer to fastboot response buffer
  35. * @format: printf style format string
  36. */
  37. void fastboot_response(const char *tag, char *response,
  38. const char *format, ...)
  39. {
  40. va_list args;
  41. strlcpy(response, tag, FASTBOOT_RESPONSE_LEN);
  42. if (format) {
  43. va_start(args, format);
  44. vsnprintf(response + strlen(response),
  45. FASTBOOT_RESPONSE_LEN - strlen(response) - 1,
  46. format, args);
  47. va_end(args);
  48. }
  49. }
  50. /**
  51. * fastboot_fail() - Write a FAIL response of the form "FAIL$reason".
  52. *
  53. * @reason: Pointer to returned reason string
  54. * @response: Pointer to fastboot response buffer
  55. */
  56. void fastboot_fail(const char *reason, char *response)
  57. {
  58. fastboot_response("FAIL", response, "%s", reason);
  59. }
  60. /**
  61. * fastboot_okay() - Write an OKAY response of the form "OKAY$reason".
  62. *
  63. * @reason: Pointer to returned reason string, or NULL to send a bare "OKAY"
  64. * @response: Pointer to fastboot response buffer
  65. */
  66. void fastboot_okay(const char *reason, char *response)
  67. {
  68. if (reason)
  69. fastboot_response("OKAY", response, "%s", reason);
  70. else
  71. fastboot_response("OKAY", response, NULL);
  72. }
  73. /**
  74. * fastboot_set_reboot_flag() - Set flag to indicate reboot-bootloader
  75. *
  76. * Set flag which indicates that we should reboot into the bootloader
  77. * following the reboot that fastboot executes after this function.
  78. *
  79. * This function should be overridden in your board file with one
  80. * which sets whatever flag your board specific Android bootloader flow
  81. * requires in order to re-enter the bootloader.
  82. */
  83. int __weak fastboot_set_reboot_flag(enum fastboot_reboot_reason reason)
  84. {
  85. #if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC_DEV)
  86. static const char * const boot_cmds[] = {
  87. [FASTBOOT_REBOOT_REASON_BOOTLOADER] = "bootonce-bootloader",
  88. [FASTBOOT_REBOOT_REASON_FASTBOOTD] = "boot-fastboot",
  89. [FASTBOOT_REBOOT_REASON_RECOVERY] = "boot-recovery"
  90. };
  91. if (reason >= FASTBOOT_REBOOT_REASONS_COUNT)
  92. return -EINVAL;
  93. return bcb_write_reboot_reason(CONFIG_FASTBOOT_FLASH_MMC_DEV, "misc", boot_cmds[reason]);
  94. #else
  95. return -EINVAL;
  96. #endif
  97. }
  98. /**
  99. * fastboot_get_progress_callback() - Return progress callback
  100. *
  101. * Return: Pointer to function called during long operations
  102. */
  103. void (*fastboot_get_progress_callback(void))(const char *)
  104. {
  105. return fastboot_progress_callback;
  106. }
  107. /**
  108. * fastboot_boot() - Execute fastboot boot command
  109. *
  110. * If ${fastboot_bootcmd} is set, run that command to execute the boot
  111. * process, if that returns, then exit the fastboot server and return
  112. * control to the caller.
  113. *
  114. * Otherwise execute "bootm <fastboot_buf_addr>", if that fails, reset
  115. * the board.
  116. */
  117. void fastboot_boot(void)
  118. {
  119. char *s;
  120. s = env_get("fastboot_bootcmd");
  121. if (s) {
  122. run_command(s, CMD_FLAG_ENV);
  123. } else {
  124. static char boot_addr_start[20];
  125. static char *const bootm_args[] = {
  126. "bootm", boot_addr_start, NULL
  127. };
  128. snprintf(boot_addr_start, sizeof(boot_addr_start) - 1,
  129. "0x%p", fastboot_buf_addr);
  130. printf("Booting kernel at %s...\n\n\n", boot_addr_start);
  131. do_bootm(NULL, 0, 2, bootm_args);
  132. /*
  133. * This only happens if image is somehow faulty so we start
  134. * over. We deliberately leave this policy to the invocation
  135. * of fastbootcmd if that's what's being run
  136. */
  137. do_reset(NULL, 0, 0, NULL);
  138. }
  139. }
  140. /**
  141. * fastboot_set_progress_callback() - set progress callback
  142. *
  143. * @progress: Pointer to progress callback
  144. *
  145. * Set a callback which is invoked periodically during long running operations
  146. * (flash and erase). This can be used (for example) by the UDP transport to
  147. * send INFO responses to keep the client alive whilst those commands are
  148. * executing.
  149. */
  150. void fastboot_set_progress_callback(void (*progress)(const char *msg))
  151. {
  152. fastboot_progress_callback = progress;
  153. }
  154. /*
  155. * fastboot_init() - initialise new fastboot protocol session
  156. *
  157. * @buf_addr: Pointer to download buffer, or NULL for default
  158. * @buf_size: Size of download buffer, or zero for default
  159. */
  160. void fastboot_init(void *buf_addr, u32 buf_size)
  161. {
  162. fastboot_buf_addr = buf_addr ? buf_addr :
  163. (void *)CONFIG_FASTBOOT_BUF_ADDR;
  164. fastboot_buf_size = buf_size ? buf_size : CONFIG_FASTBOOT_BUF_SIZE;
  165. fastboot_set_progress_callback(NULL);
  166. }