spl.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2016 Google, Inc
  4. */
  5. #include <common.h>
  6. #include <dm.h>
  7. #include <hang.h>
  8. #include <handoff.h>
  9. #include <init.h>
  10. #include <log.h>
  11. #include <os.h>
  12. #include <spl.h>
  13. #include <asm/global_data.h>
  14. #include <asm/spl.h>
  15. #include <asm/state.h>
  16. #include <test/ut.h>
  17. DECLARE_GLOBAL_DATA_PTR;
  18. int sandbox_find_next_phase(char *fname, int maxlen, bool use_img)
  19. {
  20. const char *cur_prefix, *next_prefix;
  21. int ret;
  22. cur_prefix = spl_phase_prefix(spl_phase());
  23. next_prefix = spl_phase_prefix(spl_next_phase());
  24. ret = os_find_u_boot(fname, maxlen, use_img, cur_prefix, next_prefix);
  25. if (ret)
  26. return log_msg_ret("find", ret);
  27. return 0;
  28. }
  29. /* SPL / TPL / VPL init function */
  30. void board_init_f(ulong flag)
  31. {
  32. struct sandbox_state *state = state_get_current();
  33. int ret;
  34. gd->arch.ram_buf = state->ram_buf;
  35. gd->ram_size = state->ram_size;
  36. ret = spl_early_init();
  37. if (ret) {
  38. debug("spl_early_init() failed: %d\n", ret);
  39. hang();
  40. }
  41. preloader_console_init();
  42. }
  43. void board_boot_order(u32 *spl_boot_list)
  44. {
  45. spl_boot_list[0] = BOOT_DEVICE_VBE;
  46. spl_boot_list[1] = BOOT_DEVICE_BOARD;
  47. }
  48. static int spl_board_load_file(struct spl_image_info *spl_image,
  49. struct spl_boot_device *bootdev)
  50. {
  51. char fname[256];
  52. int ret;
  53. ret = sandbox_find_next_phase(fname, sizeof(fname), false);
  54. if (ret) {
  55. printf("(%s not found, error %d)\n", fname, ret);
  56. return ret;
  57. }
  58. /*
  59. * Set up spl_image to boot from jump_to_image_no_args(). Allocate this
  60. * outsdide the RAM buffer (i.e. don't use strdup()).
  61. */
  62. spl_image->arg = os_malloc(strlen(fname) + 1);
  63. if (!spl_image->arg)
  64. return log_msg_ret("exec", -ENOMEM);
  65. strcpy(spl_image->arg, fname);
  66. spl_image->flags = SPL_SANDBOXF_ARG_IS_FNAME;
  67. return 0;
  68. }
  69. SPL_LOAD_IMAGE_METHOD("sandbox_file", 9, BOOT_DEVICE_BOARD,
  70. spl_board_load_file);
  71. static int load_from_image(struct spl_image_info *spl_image,
  72. struct spl_boot_device *bootdev)
  73. {
  74. struct sandbox_state *state = state_get_current();
  75. enum u_boot_phase next_phase;
  76. const char *fname;
  77. ulong pos, size;
  78. int full_size;
  79. void *buf;
  80. int ret;
  81. if (!IS_ENABLED(CONFIG_SANDBOX_VPL))
  82. return -ENOENT;
  83. next_phase = spl_next_phase();
  84. pos = spl_get_image_pos();
  85. size = spl_get_image_size();
  86. if (pos == BINMAN_SYM_MISSING || size == BINMAN_SYM_MISSING) {
  87. log_debug("No image found\n");
  88. return -ENOENT;
  89. }
  90. log_info("Reading from pos %lx size %lx\n", pos, size);
  91. /*
  92. * Set up spl_image to boot from jump_to_image_no_args(). Allocate this
  93. * outside the RAM buffer (i.e. don't use strdup()).
  94. */
  95. fname = state->prog_fname ? state->prog_fname : state->argv[0];
  96. ret = os_read_file(fname, &buf, &full_size);
  97. if (ret)
  98. return log_msg_ret("rd", -ENOMEM);
  99. spl_image->flags = SPL_SANDBOXF_ARG_IS_BUF;
  100. spl_image->arg = buf;
  101. spl_image->offset = pos;
  102. spl_image->size = size;
  103. return 0;
  104. }
  105. SPL_LOAD_IMAGE_METHOD("sandbox_image", 7, BOOT_DEVICE_BOARD, load_from_image);
  106. void spl_board_init(void)
  107. {
  108. struct sandbox_state *state = state_get_current();
  109. if (state->run_unittests) {
  110. struct unit_test *tests = UNIT_TEST_ALL_START();
  111. const int count = UNIT_TEST_ALL_COUNT();
  112. int ret;
  113. ret = ut_run_list("spl", NULL, tests, count,
  114. state->select_unittests, 1, false, NULL);
  115. /* continue execution into U-Boot */
  116. }
  117. }
  118. void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
  119. {
  120. switch (spl_image->flags) {
  121. case SPL_SANDBOXF_ARG_IS_FNAME: {
  122. const char *fname = spl_image->arg;
  123. if (fname) {
  124. os_fd_restore();
  125. os_spl_to_uboot(fname);
  126. } else {
  127. log_err("No filename provided for U-Boot\n");
  128. }
  129. break;
  130. }
  131. case SPL_SANDBOXF_ARG_IS_BUF: {
  132. int ret;
  133. ret = os_jump_to_image(spl_image->arg + spl_image->offset,
  134. spl_image->size);
  135. if (ret)
  136. log_err("Failed to load image\n");
  137. break;
  138. }
  139. default:
  140. log_err("Invalid flags\n");
  141. break;
  142. }
  143. hang();
  144. }
  145. int handoff_arch_save(struct spl_handoff *ho)
  146. {
  147. ho->arch.magic = TEST_HANDOFF_MAGIC;
  148. return 0;
  149. }