blob: 2c31777fcd3af2bc5c738f492a465df280197933 [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
Peng Fan1a7e6252019-08-22 07:42:33 +000017static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image,
18 struct spl_load_info *info,
19 struct container_hdr *container,
20 int image_index,
Sean Anderson7d8d6132023-11-08 11:48:40 -050021 ulong container_offset)
Peng Fan1a7e6252019-08-22 07:42:33 +000022{
23 struct boot_img_t *images;
Sean Anderson7d8d6132023-11-08 11:48:40 -050024 ulong offset, overhead, size;
Peng Fan1a7e6252019-08-22 07:42:33 +000025
26 if (image_index > container->num_images) {
27 debug("Invalid image number\n");
28 return NULL;
29 }
30
31 images = (struct boot_img_t *)((u8 *)container +
32 sizeof(struct container_hdr));
33
Sean Anderson35f15fe2023-11-08 11:48:43 -050034 if (!IS_ALIGNED(images[image_index].offset, spl_get_bl_len(info))) {
Peng Fan1a7e6252019-08-22 07:42:33 +000035 printf("%s: image%d offset not aligned to %u\n",
Sean Anderson35f15fe2023-11-08 11:48:43 -050036 __func__, image_index, spl_get_bl_len(info));
Peng Fan1a7e6252019-08-22 07:42:33 +000037 return NULL;
38 }
39
Sean Anderson35f15fe2023-11-08 11:48:43 -050040 size = ALIGN(images[image_index].size, spl_get_bl_len(info));
Sean Anderson7d8d6132023-11-08 11:48:40 -050041 offset = images[image_index].offset + container_offset;
Peng Fan1a7e6252019-08-22 07:42:33 +000042
Sean Anderson7d8d6132023-11-08 11:48:40 -050043 debug("%s: container: %p offset: %lu size: %lu\n", __func__,
44 container, offset, size);
45 if (info->read(info, offset, size,
46 map_sysmem(images[image_index].dst - overhead,
Sean Andersonb27c5f82023-11-08 11:48:41 -050047 images[image_index].size)) <
48 images[image_index].size) {
Peng Fan1a7e6252019-08-22 07:42:33 +000049 printf("%s wrong\n", __func__);
50 return NULL;
51 }
Peng Fanf1e0f9f2019-09-25 08:11:14 +000052
53#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +080054 if (ahab_verify_cntr_image(&images[image_index], image_index))
Peng Fanf1e0f9f2019-09-25 08:11:14 +000055 return NULL;
Peng Fanf1e0f9f2019-09-25 08:11:14 +000056#endif
Peng Fan1a7e6252019-08-22 07:42:33 +000057
58 return &images[image_index];
59}
60
61static int read_auth_container(struct spl_image_info *spl_image,
Sean Anderson7d8d6132023-11-08 11:48:40 -050062 struct spl_load_info *info, ulong offset)
Peng Fan1a7e6252019-08-22 07:42:33 +000063{
64 struct container_hdr *container = NULL;
65 u16 length;
Peng Fanf1e0f9f2019-09-25 08:11:14 +000066 int i, size, ret = 0;
Peng Fan1a7e6252019-08-22 07:42:33 +000067
Sean Anderson35f15fe2023-11-08 11:48:43 -050068 size = ALIGN(CONTAINER_HDR_ALIGNMENT, spl_get_bl_len(info));
Peng Fan1a7e6252019-08-22 07:42:33 +000069
70 /*
71 * It will not override the ATF code, so safe to use it here,
72 * no need malloc
73 */
Nitin Gargf39c1f22023-06-15 18:09:22 +080074 container = malloc(size);
75 if (!container)
76 return -ENOMEM;
Peng Fan1a7e6252019-08-22 07:42:33 +000077
Sean Anderson7d8d6132023-11-08 11:48:40 -050078 debug("%s: container: %p offset: %lu size: %u\n", __func__,
79 container, offset, size);
Sean Andersonb27c5f82023-11-08 11:48:41 -050080 if (info->read(info, offset, size, container) <
81 CONTAINER_HDR_ALIGNMENT) {
Nitin Gargf39c1f22023-06-15 18:09:22 +080082 ret = -EIO;
83 goto end;
84 }
Peng Fan1a7e6252019-08-22 07:42:33 +000085
Sean Andersonc5126682023-10-14 16:47:43 -040086 if (!valid_container_hdr(container)) {
Sean Anderson5d5c7bd2023-10-14 16:47:42 -040087 log_err("Wrong container header\n");
Nitin Gargf39c1f22023-06-15 18:09:22 +080088 ret = -ENOENT;
89 goto end;
Peng Fan1a7e6252019-08-22 07:42:33 +000090 }
91
92 if (!container->num_images) {
Sean Anderson5d5c7bd2023-10-14 16:47:42 -040093 log_err("Wrong container, no image found\n");
Nitin Gargf39c1f22023-06-15 18:09:22 +080094 ret = -ENOENT;
95 goto end;
Peng Fan1a7e6252019-08-22 07:42:33 +000096 }
97
98 length = container->length_lsb + (container->length_msb << 8);
99 debug("Container length %u\n", length);
100
101 if (length > CONTAINER_HDR_ALIGNMENT) {
Sean Anderson35f15fe2023-11-08 11:48:43 -0500102 size = ALIGN(length, spl_get_bl_len(info));
Peng Fan1a7e6252019-08-22 07:42:33 +0000103
Nitin Gargf39c1f22023-06-15 18:09:22 +0800104 free(container);
105 container = malloc(size);
106 if (!container)
107 return -ENOMEM;
Peng Fan1a7e6252019-08-22 07:42:33 +0000108
Sean Anderson7d8d6132023-11-08 11:48:40 -0500109 debug("%s: container: %p offset: %lu size: %u\n",
110 __func__, container, offset, size);
Sean Andersonb27c5f82023-11-08 11:48:41 -0500111 if (info->read(info, offset, size, container) < length) {
Nitin Gargf39c1f22023-06-15 18:09:22 +0800112 ret = -EIO;
113 goto end;
114 }
Peng Fan1a7e6252019-08-22 07:42:33 +0000115 }
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000116
117#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +0800118 ret = ahab_auth_cntr_hdr(container, length);
119 if (ret)
Nitin Gargf39c1f22023-06-15 18:09:22 +0800120 goto end_auth;
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000121#endif
Peng Fan1a7e6252019-08-22 07:42:33 +0000122
123 for (i = 0; i < container->num_images; i++) {
124 struct boot_img_t *image = read_auth_image(spl_image, info,
125 container, i,
Sean Anderson7d8d6132023-11-08 11:48:40 -0500126 offset);
Peng Fan1a7e6252019-08-22 07:42:33 +0000127
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000128 if (!image) {
129 ret = -EINVAL;
130 goto end_auth;
131 }
Peng Fan1a7e6252019-08-22 07:42:33 +0000132
133 if (i == 0) {
134 spl_image->load_addr = image->dst;
135 spl_image->entry_point = image->entry;
136 }
137 }
138
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000139end_auth:
140#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +0800141 ahab_auth_release();
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000142#endif
Nitin Gargf39c1f22023-06-15 18:09:22 +0800143
144end:
145 free(container);
146
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000147 return ret;
Peng Fan1a7e6252019-08-22 07:42:33 +0000148}
149
150int spl_load_imx_container(struct spl_image_info *spl_image,
Sean Anderson7d8d6132023-11-08 11:48:40 -0500151 struct spl_load_info *info, ulong offset)
Peng Fan1a7e6252019-08-22 07:42:33 +0000152{
Sean Anderson7d8d6132023-11-08 11:48:40 -0500153 return read_auth_container(spl_image, info, offset);
Peng Fan1a7e6252019-08-22 07:42:33 +0000154}