image.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2019 NXP
  4. */
  5. #include <common.h>
  6. #include <errno.h>
  7. #include <log.h>
  8. #include <malloc.h>
  9. #include <asm/io.h>
  10. #include <mmc.h>
  11. #include <spi_flash.h>
  12. #include <nand.h>
  13. #include <asm/arch/image.h>
  14. #include <asm/arch/sys_proto.h>
  15. #include <asm/mach-imx/boot_mode.h>
  16. #define MMC_DEV 0
  17. #define QSPI_DEV 1
  18. #define NAND_DEV 2
  19. #define QSPI_NOR_DEV 3
  20. static int __get_container_size(ulong addr)
  21. {
  22. struct container_hdr *phdr;
  23. struct boot_img_t *img_entry;
  24. struct signature_block_hdr *sign_hdr;
  25. u8 i = 0;
  26. u32 max_offset = 0, img_end;
  27. phdr = (struct container_hdr *)addr;
  28. if (phdr->tag != 0x87 && phdr->version != 0x0) {
  29. debug("Wrong container header\n");
  30. return -EFAULT;
  31. }
  32. max_offset = sizeof(struct container_hdr);
  33. img_entry = (struct boot_img_t *)(addr + sizeof(struct container_hdr));
  34. for (i = 0; i < phdr->num_images; i++) {
  35. img_end = img_entry->offset + img_entry->size;
  36. if (img_end > max_offset)
  37. max_offset = img_end;
  38. debug("img[%u], end = 0x%x\n", i, img_end);
  39. img_entry++;
  40. }
  41. if (phdr->sig_blk_offset != 0) {
  42. sign_hdr = (struct signature_block_hdr *)(addr + phdr->sig_blk_offset);
  43. u16 len = sign_hdr->length_lsb + (sign_hdr->length_msb << 8);
  44. if (phdr->sig_blk_offset + len > max_offset)
  45. max_offset = phdr->sig_blk_offset + len;
  46. debug("sigblk, end = 0x%x\n", phdr->sig_blk_offset + len);
  47. }
  48. return max_offset;
  49. }
  50. static int get_container_size(void *dev, int dev_type, unsigned long offset)
  51. {
  52. u8 *buf = malloc(CONTAINER_HDR_ALIGNMENT);
  53. int ret = 0;
  54. if (!buf) {
  55. printf("Malloc buffer failed\n");
  56. return -ENOMEM;
  57. }
  58. #ifdef CONFIG_SPL_MMC_SUPPORT
  59. if (dev_type == MMC_DEV) {
  60. unsigned long count = 0;
  61. struct mmc *mmc = (struct mmc *)dev;
  62. count = blk_dread(mmc_get_blk_desc(mmc),
  63. offset / mmc->read_bl_len,
  64. CONTAINER_HDR_ALIGNMENT / mmc->read_bl_len,
  65. buf);
  66. if (count == 0) {
  67. printf("Read container image from MMC/SD failed\n");
  68. return -EIO;
  69. }
  70. }
  71. #endif
  72. #ifdef CONFIG_SPL_SPI_LOAD
  73. if (dev_type == QSPI_DEV) {
  74. struct spi_flash *flash = (struct spi_flash *)dev;
  75. ret = spi_flash_read(flash, offset,
  76. CONTAINER_HDR_ALIGNMENT, buf);
  77. if (ret != 0) {
  78. printf("Read container image from QSPI failed\n");
  79. return -EIO;
  80. }
  81. }
  82. #endif
  83. #ifdef CONFIG_SPL_NAND_SUPPORT
  84. if (dev_type == NAND_DEV) {
  85. ret = nand_spl_load_image(offset, CONTAINER_HDR_ALIGNMENT,
  86. buf);
  87. if (ret != 0) {
  88. printf("Read container image from NAND failed\n");
  89. return -EIO;
  90. }
  91. }
  92. #endif
  93. #ifdef CONFIG_SPL_NOR_SUPPORT
  94. if (dev_type == QSPI_NOR_DEV)
  95. memcpy(buf, (const void *)offset, CONTAINER_HDR_ALIGNMENT);
  96. #endif
  97. ret = __get_container_size((ulong)buf);
  98. free(buf);
  99. return ret;
  100. }
  101. static unsigned long get_boot_device_offset(void *dev, int dev_type)
  102. {
  103. unsigned long offset = 0;
  104. if (dev_type == MMC_DEV) {
  105. struct mmc *mmc = (struct mmc *)dev;
  106. if (IS_SD(mmc) || mmc->part_config == MMCPART_NOAVAILABLE) {
  107. offset = CONTAINER_HDR_MMCSD_OFFSET;
  108. } else {
  109. u8 part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
  110. if (part == 1 || part == 2) {
  111. if (is_imx8qxp() && is_soc_rev(CHIP_REV_B))
  112. offset = CONTAINER_HDR_MMCSD_OFFSET;
  113. else
  114. offset = CONTAINER_HDR_EMMC_OFFSET;
  115. } else {
  116. offset = CONTAINER_HDR_MMCSD_OFFSET;
  117. }
  118. }
  119. } else if (dev_type == QSPI_DEV) {
  120. offset = CONTAINER_HDR_QSPI_OFFSET;
  121. } else if (dev_type == NAND_DEV) {
  122. offset = CONTAINER_HDR_NAND_OFFSET;
  123. } else if (dev_type == QSPI_NOR_DEV) {
  124. offset = CONTAINER_HDR_QSPI_OFFSET + 0x08000000;
  125. }
  126. return offset;
  127. }
  128. static int get_imageset_end(void *dev, int dev_type)
  129. {
  130. unsigned long offset1 = 0, offset2 = 0;
  131. int value_container[2];
  132. offset1 = get_boot_device_offset(dev, dev_type);
  133. offset2 = CONTAINER_HDR_ALIGNMENT + offset1;
  134. value_container[0] = get_container_size(dev, dev_type, offset1);
  135. if (value_container[0] < 0) {
  136. printf("Parse seco container failed %d\n", value_container[0]);
  137. return value_container[0];
  138. }
  139. debug("seco container size 0x%x\n", value_container[0]);
  140. value_container[1] = get_container_size(dev, dev_type, offset2);
  141. if (value_container[1] < 0) {
  142. debug("Parse scu container failed %d, only seco container\n",
  143. value_container[1]);
  144. /* return seco container total size */
  145. return value_container[0] + offset1;
  146. }
  147. debug("scu container size 0x%x\n", value_container[1]);
  148. return value_container[1] + offset2;
  149. }
  150. #ifdef CONFIG_SPL_SPI_LOAD
  151. unsigned long spl_spi_get_uboot_offs(struct spi_flash *flash)
  152. {
  153. int end;
  154. end = get_imageset_end(flash, QSPI_DEV);
  155. end = ROUND(end, SZ_1K);
  156. printf("Load image from QSPI 0x%x\n", end);
  157. return end;
  158. }
  159. #endif
  160. #ifdef CONFIG_SPL_MMC_SUPPORT
  161. unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
  162. unsigned long raw_sect)
  163. {
  164. int end;
  165. end = get_imageset_end(mmc, MMC_DEV);
  166. end = ROUND(end, SZ_1K);
  167. printf("Load image from MMC/SD 0x%x\n", end);
  168. return end / mmc->read_bl_len;
  169. }
  170. #endif
  171. #ifdef CONFIG_SPL_NAND_SUPPORT
  172. uint32_t spl_nand_get_uboot_raw_page(void)
  173. {
  174. int end;
  175. end = get_imageset_end((void *)NULL, NAND_DEV);
  176. end = ROUND(end, SZ_16K);
  177. printf("Load image from NAND 0x%x\n", end);
  178. return end;
  179. }
  180. #endif
  181. #ifdef CONFIG_SPL_NOR_SUPPORT
  182. unsigned long spl_nor_get_uboot_base(void)
  183. {
  184. int end;
  185. /* Calculate the image set end,
  186. * if it is less than CONFIG_SYS_UBOOT_BASE(0x8281000),
  187. * we use CONFIG_SYS_UBOOT_BASE
  188. * Otherwise, use the calculated address
  189. */
  190. end = get_imageset_end((void *)NULL, QSPI_NOR_DEV);
  191. if (end <= CONFIG_SYS_UBOOT_BASE)
  192. end = CONFIG_SYS_UBOOT_BASE;
  193. else
  194. end = ROUND(end, SZ_1K);
  195. printf("Load image from NOR 0x%x\n", end);
  196. return end;
  197. }
  198. #endif