blob: b3565efb225ad83b5b25c959b75c268de5c03c55 [file] [log] [blame]
Peng Fan1a7e6252019-08-22 07:42:33 +00001// SPDX-License-Identifier: GPL-2.0+
2/*
Ye Li185af302023-06-15 18:09:23 +08003 * Copyright 2018-2021 NXP
Peng Fan1a7e6252019-08-22 07:42:33 +00004 */
5
Sean Anderson5d5c7bd2023-10-14 16:47:42 -04006#define LOG_CATEGORY LOGC_ARCH
Nitin Gargf39c1f22023-06-15 18:09:22 +08007#include <stdlib.h>
Peng Fan1a7e6252019-08-22 07:42:33 +00008#include <errno.h>
Sean Anderson952ed672023-10-14 16:47:44 -04009#include <imx_container.h>
Simon Glass0f2af882020-05-10 11:40:05 -060010#include <log.h>
Sean Anderson5ff77722023-10-14 16:47:55 -040011#include <mapmem.h>
Peng Fan1a7e6252019-08-22 07:42:33 +000012#include <spl.h>
Peng Fanb5906342021-08-07 16:00:38 +080013#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +080014#include <asm/mach-imx/ahab.h>
Peng Fanb5906342021-08-07 16:00:38 +080015#endif
Peng Fanf1e0f9f2019-09-25 08:11:14 +000016
Ye Li87178ed2025-04-28 18:37:36 +080017__weak bool arch_check_dst_in_secure(void *start, ulong size)
18{
19 return false;
20}
21
22__weak void *arch_get_container_trampoline(void)
23{
24 return NULL;
25}
26
Peng Fan1a7e6252019-08-22 07:42:33 +000027static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image,
28 struct spl_load_info *info,
29 struct container_hdr *container,
30 int image_index,
Sean Anderson7d8d6132023-11-08 11:48:40 -050031 ulong container_offset)
Peng Fan1a7e6252019-08-22 07:42:33 +000032{
33 struct boot_img_t *images;
Sean Anderson7d8d6132023-11-08 11:48:40 -050034 ulong offset, overhead, size;
Ye Li87178ed2025-04-28 18:37:36 +080035 void *buf, *trampoline;
Peng Fan1a7e6252019-08-22 07:42:33 +000036
37 if (image_index > container->num_images) {
38 debug("Invalid image number\n");
39 return NULL;
40 }
41
42 images = (struct boot_img_t *)((u8 *)container +
43 sizeof(struct container_hdr));
44
Sean Anderson35f15fe2023-11-08 11:48:43 -050045 if (!IS_ALIGNED(images[image_index].offset, spl_get_bl_len(info))) {
Peng Fan1a7e6252019-08-22 07:42:33 +000046 printf("%s: image%d offset not aligned to %u\n",
Sean Anderson35f15fe2023-11-08 11:48:43 -050047 __func__, image_index, spl_get_bl_len(info));
Peng Fan1a7e6252019-08-22 07:42:33 +000048 return NULL;
49 }
50
Sean Anderson35f15fe2023-11-08 11:48:43 -050051 size = ALIGN(images[image_index].size, spl_get_bl_len(info));
Sean Anderson7d8d6132023-11-08 11:48:40 -050052 offset = images[image_index].offset + container_offset;
Peng Fan1a7e6252019-08-22 07:42:33 +000053
Sean Anderson7d8d6132023-11-08 11:48:40 -050054 debug("%s: container: %p offset: %lu size: %lu\n", __func__,
55 container, offset, size);
Ye Li87178ed2025-04-28 18:37:36 +080056
57 buf = map_sysmem(images[image_index].dst - overhead, images[image_index].size);
58 if (IS_ENABLED(CONFIG_SPL_IMX_CONTAINER_USE_TRAMPOLINE) &&
59 arch_check_dst_in_secure(buf, size)) {
60 trampoline = arch_get_container_trampoline();
61 if (!trampoline) {
62 printf("%s: trampoline size is zero\n", __func__);
63 return NULL;
64 }
65
66 if (info->read(info, offset, size, trampoline) < images[image_index].size) {
67 printf("%s: failed to load image to a trampoline buffer\n", __func__);
68 return NULL;
69 }
70
71 memcpy(buf, trampoline, images[image_index].size);
72 } else {
73 if (info->read(info, offset, size, buf) < images[image_index].size) {
74 printf("%s: failed to load image to a non-secure region\n", __func__);
75 return NULL;
76 }
Peng Fan1a7e6252019-08-22 07:42:33 +000077 }
Peng Fanf1e0f9f2019-09-25 08:11:14 +000078
79#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +080080 if (ahab_verify_cntr_image(&images[image_index], image_index))
Peng Fanf1e0f9f2019-09-25 08:11:14 +000081 return NULL;
Peng Fanf1e0f9f2019-09-25 08:11:14 +000082#endif
Peng Fan1a7e6252019-08-22 07:42:33 +000083
84 return &images[image_index];
85}
86
87static int read_auth_container(struct spl_image_info *spl_image,
Sean Anderson7d8d6132023-11-08 11:48:40 -050088 struct spl_load_info *info, ulong offset)
Peng Fan1a7e6252019-08-22 07:42:33 +000089{
90 struct container_hdr *container = NULL;
91 u16 length;
Peng Fanf1e0f9f2019-09-25 08:11:14 +000092 int i, size, ret = 0;
Peng Fan1a7e6252019-08-22 07:42:33 +000093
Sean Anderson35f15fe2023-11-08 11:48:43 -050094 size = ALIGN(CONTAINER_HDR_ALIGNMENT, spl_get_bl_len(info));
Peng Fan1a7e6252019-08-22 07:42:33 +000095
96 /*
97 * It will not override the ATF code, so safe to use it here,
98 * no need malloc
99 */
Nitin Gargf39c1f22023-06-15 18:09:22 +0800100 container = malloc(size);
101 if (!container)
102 return -ENOMEM;
Peng Fan1a7e6252019-08-22 07:42:33 +0000103
Sean Anderson7d8d6132023-11-08 11:48:40 -0500104 debug("%s: container: %p offset: %lu size: %u\n", __func__,
105 container, offset, size);
Sean Andersonb27c5f82023-11-08 11:48:41 -0500106 if (info->read(info, offset, size, container) <
107 CONTAINER_HDR_ALIGNMENT) {
Nitin Gargf39c1f22023-06-15 18:09:22 +0800108 ret = -EIO;
109 goto end;
110 }
Peng Fan1a7e6252019-08-22 07:42:33 +0000111
Sean Andersonc5126682023-10-14 16:47:43 -0400112 if (!valid_container_hdr(container)) {
Sean Anderson5d5c7bd2023-10-14 16:47:42 -0400113 log_err("Wrong container header\n");
Nitin Gargf39c1f22023-06-15 18:09:22 +0800114 ret = -ENOENT;
115 goto end;
Peng Fan1a7e6252019-08-22 07:42:33 +0000116 }
117
118 if (!container->num_images) {
Sean Anderson5d5c7bd2023-10-14 16:47:42 -0400119 log_err("Wrong container, no image found\n");
Nitin Gargf39c1f22023-06-15 18:09:22 +0800120 ret = -ENOENT;
121 goto end;
Peng Fan1a7e6252019-08-22 07:42:33 +0000122 }
123
124 length = container->length_lsb + (container->length_msb << 8);
125 debug("Container length %u\n", length);
126
127 if (length > CONTAINER_HDR_ALIGNMENT) {
Sean Anderson35f15fe2023-11-08 11:48:43 -0500128 size = ALIGN(length, spl_get_bl_len(info));
Peng Fan1a7e6252019-08-22 07:42:33 +0000129
Nitin Gargf39c1f22023-06-15 18:09:22 +0800130 free(container);
131 container = malloc(size);
132 if (!container)
133 return -ENOMEM;
Peng Fan1a7e6252019-08-22 07:42:33 +0000134
Sean Anderson7d8d6132023-11-08 11:48:40 -0500135 debug("%s: container: %p offset: %lu size: %u\n",
136 __func__, container, offset, size);
Sean Andersonb27c5f82023-11-08 11:48:41 -0500137 if (info->read(info, offset, size, container) < length) {
Nitin Gargf39c1f22023-06-15 18:09:22 +0800138 ret = -EIO;
139 goto end;
140 }
Peng Fan1a7e6252019-08-22 07:42:33 +0000141 }
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000142
143#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +0800144 ret = ahab_auth_cntr_hdr(container, length);
145 if (ret)
Nitin Gargf39c1f22023-06-15 18:09:22 +0800146 goto end_auth;
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000147#endif
Peng Fan1a7e6252019-08-22 07:42:33 +0000148
149 for (i = 0; i < container->num_images; i++) {
150 struct boot_img_t *image = read_auth_image(spl_image, info,
151 container, i,
Sean Anderson7d8d6132023-11-08 11:48:40 -0500152 offset);
Peng Fan1a7e6252019-08-22 07:42:33 +0000153
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000154 if (!image) {
155 ret = -EINVAL;
156 goto end_auth;
157 }
Peng Fan1a7e6252019-08-22 07:42:33 +0000158
159 if (i == 0) {
160 spl_image->load_addr = image->dst;
161 spl_image->entry_point = image->entry;
162 }
163 }
164
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000165end_auth:
166#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +0800167 ahab_auth_release();
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000168#endif
Nitin Gargf39c1f22023-06-15 18:09:22 +0800169
170end:
171 free(container);
172
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000173 return ret;
Peng Fan1a7e6252019-08-22 07:42:33 +0000174}
175
176int spl_load_imx_container(struct spl_image_info *spl_image,
Sean Anderson7d8d6132023-11-08 11:48:40 -0500177 struct spl_load_info *info, ulong offset)
Peng Fan1a7e6252019-08-22 07:42:33 +0000178{
Sean Anderson7d8d6132023-11-08 11:48:40 -0500179 return read_auth_container(spl_image, info, offset);
Peng Fan1a7e6252019-08-22 07:42:33 +0000180}