arm_io_storage.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*
  2. * Copyright (c) 2015-2021, ARM Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <common/debug.h>
  7. #include <drivers/fwu/fwu_metadata.h>
  8. #include <drivers/io/io_driver.h>
  9. #include <drivers/io/io_fip.h>
  10. #include <drivers/io/io_memmap.h>
  11. #include <drivers/io/io_storage.h>
  12. #include <drivers/partition/partition.h>
  13. #include <lib/utils.h>
  14. #include <plat/arm/common/arm_fconf_getter.h>
  15. #include <plat/arm/common/arm_fconf_io_storage.h>
  16. #include <plat/arm/common/plat_arm.h>
  17. #include <plat/common/platform.h>
  18. #include <platform_def.h>
  19. /* IO devices */
  20. static const io_dev_connector_t *fip_dev_con;
  21. uintptr_t fip_dev_handle;
  22. static const io_dev_connector_t *memmap_dev_con;
  23. uintptr_t memmap_dev_handle;
  24. #if ARM_GPT_SUPPORT
  25. /* fip partition names */
  26. static const char * const fip_part_names[] = {"FIP_A", "FIP_B"};
  27. CASSERT(sizeof(fip_part_names)/sizeof(char *) == NR_OF_FW_BANKS,
  28. assert_fip_partition_names_missing);
  29. #endif /* ARM_GPT_SUPPORT */
  30. /* Weak definitions may be overridden in specific ARM standard platform */
  31. #pragma weak plat_arm_io_setup
  32. #pragma weak plat_arm_get_alt_image_source
  33. int open_fip(const uintptr_t spec)
  34. {
  35. int result;
  36. uintptr_t local_image_handle;
  37. /* See if a Firmware Image Package is available */
  38. result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
  39. if (result == 0) {
  40. result = io_open(fip_dev_handle, spec, &local_image_handle);
  41. if (result == 0) {
  42. VERBOSE("Using FIP\n");
  43. io_close(local_image_handle);
  44. }
  45. }
  46. return result;
  47. }
  48. int open_memmap(const uintptr_t spec)
  49. {
  50. int result;
  51. uintptr_t local_image_handle;
  52. result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
  53. if (result == 0) {
  54. result = io_open(memmap_dev_handle, spec, &local_image_handle);
  55. if (result == 0) {
  56. VERBOSE("Using Memmap\n");
  57. io_close(local_image_handle);
  58. }
  59. }
  60. return result;
  61. }
  62. int arm_io_setup(void)
  63. {
  64. int io_result;
  65. io_result = register_io_dev_fip(&fip_dev_con);
  66. if (io_result < 0) {
  67. return io_result;
  68. }
  69. io_result = register_io_dev_memmap(&memmap_dev_con);
  70. if (io_result < 0) {
  71. return io_result;
  72. }
  73. /* Open connections to devices and cache the handles */
  74. io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
  75. &fip_dev_handle);
  76. if (io_result < 0) {
  77. return io_result;
  78. }
  79. io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
  80. &memmap_dev_handle);
  81. return io_result;
  82. }
  83. void plat_arm_io_setup(void)
  84. {
  85. int err;
  86. err = arm_io_setup();
  87. if (err < 0) {
  88. panic();
  89. }
  90. }
  91. int plat_arm_get_alt_image_source(
  92. unsigned int image_id __unused,
  93. uintptr_t *dev_handle __unused,
  94. uintptr_t *image_spec __unused)
  95. {
  96. /* By default do not try an alternative */
  97. return -ENOENT;
  98. }
  99. /* Return an IO device handle and specification which can be used to access
  100. * an image. Use this to enforce platform load policy */
  101. int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
  102. uintptr_t *image_spec)
  103. {
  104. int result;
  105. const struct plat_io_policy *policy;
  106. policy = FCONF_GET_PROPERTY(arm, io_policies, image_id);
  107. assert(policy->check != NULL);
  108. result = policy->check(policy->image_spec);
  109. if (result == 0) {
  110. *image_spec = policy->image_spec;
  111. *dev_handle = *(policy->dev_handle);
  112. } else {
  113. VERBOSE("Trying alternative IO\n");
  114. result = plat_arm_get_alt_image_source(image_id, dev_handle,
  115. image_spec);
  116. }
  117. return result;
  118. }
  119. /*
  120. * See if a Firmware Image Package is available,
  121. * by checking if TOC is valid or not.
  122. */
  123. bool arm_io_is_toc_valid(void)
  124. {
  125. return (io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID) == 0);
  126. }
  127. #if ARM_GPT_SUPPORT
  128. /******************************************************************************
  129. * Retrieve partition entry details such as offset and length, and set these
  130. * details in the I/O policy of the requested image.
  131. *
  132. * @image_id: image id whose I/O policy to be updated
  133. *
  134. * @part_name: partition name whose details to be retrieved
  135. *
  136. * Returns 0 on success, error otherwise
  137. * Alongside, returns device handle and image specification of requested
  138. * image.
  139. ******************************************************************************/
  140. int arm_set_image_source(unsigned int image_id, const char *part_name,
  141. uintptr_t *dev_handle, uintptr_t *image_spec)
  142. {
  143. const partition_entry_t *entry = get_partition_entry(part_name);
  144. if (entry == NULL) {
  145. ERROR("Unable to find the %s partition\n", part_name);
  146. return -ENOENT;
  147. }
  148. struct plat_io_policy *policy = FCONF_GET_PROPERTY(arm,
  149. io_policies,
  150. image_id);
  151. assert(policy != NULL);
  152. assert(policy->image_spec != 0UL);
  153. io_block_spec_t *spec = (io_block_spec_t *)policy->image_spec;
  154. /* set offset and length of the image */
  155. spec->offset = PLAT_ARM_FLASH_IMAGE_BASE + entry->start;
  156. spec->length = entry->length;
  157. *dev_handle = *(policy->dev_handle);
  158. *image_spec = policy->image_spec;
  159. return 0;
  160. }
  161. /*******************************************************************************
  162. * Set the source offset and length of the FIP image in its I/O policy.
  163. *
  164. * @active_fw_bank_idx: active firmware bank index gathered from FWU metadata.
  165. ******************************************************************************/
  166. void arm_set_fip_addr(uint32_t active_fw_bank_idx)
  167. {
  168. uintptr_t dev_handle __unused;
  169. uintptr_t image_spec __unused;
  170. assert(active_fw_bank_idx < NR_OF_FW_BANKS);
  171. INFO("Booting with partition %s\n", fip_part_names[active_fw_bank_idx]);
  172. int result = arm_set_image_source(FIP_IMAGE_ID,
  173. fip_part_names[active_fw_bank_idx],
  174. &dev_handle,
  175. &image_spec);
  176. if (result != 0) {
  177. panic();
  178. }
  179. }
  180. #endif /* ARM_GPT_SUPPORT */
  181. #if PSA_FWU_SUPPORT
  182. /*******************************************************************************
  183. * Read the FIP partition of the GPT image corresponding to the active firmware
  184. * bank to get its offset and length, and update these details in the I/O policy
  185. * of the FIP image.
  186. ******************************************************************************/
  187. void plat_fwu_set_images_source(const struct fwu_metadata *metadata)
  188. {
  189. arm_set_fip_addr(metadata->active_index);
  190. }
  191. /*******************************************************************************
  192. * Read the requested FWU metadata partition of the GPT image to get its offset
  193. * and length, and update these details in the I/O policy of the requested FWU
  194. * metadata image.
  195. ******************************************************************************/
  196. int plat_fwu_set_metadata_image_source(unsigned int image_id,
  197. uintptr_t *dev_handle,
  198. uintptr_t *image_spec)
  199. {
  200. int result = -1;
  201. if (image_id == FWU_METADATA_IMAGE_ID) {
  202. result = arm_set_image_source(FWU_METADATA_IMAGE_ID,
  203. "FWU-Metadata",
  204. dev_handle,
  205. image_spec);
  206. } else if (image_id == BKUP_FWU_METADATA_IMAGE_ID) {
  207. result = arm_set_image_source(BKUP_FWU_METADATA_IMAGE_ID,
  208. "Bkup-FWU-Metadata",
  209. dev_handle,
  210. image_spec);
  211. }
  212. return result;
  213. }
  214. #endif /* PSA_FWU_SUPPORT */