blob: ad89a99fb23ff7edf04b59a99d40985a0e29b3db [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
Peng Fan1a7e6252019-08-22 07:42:33 +00007#include <common.h>
Nitin Gargf39c1f22023-06-15 18:09:22 +08008#include <stdlib.h>
Peng Fan1a7e6252019-08-22 07:42:33 +00009#include <errno.h>
Sean Anderson952ed672023-10-14 16:47:44 -040010#include <imx_container.h>
Simon Glass0f2af882020-05-10 11:40:05 -060011#include <log.h>
Sean Anderson5ff77722023-10-14 16:47:55 -040012#include <mapmem.h>
Peng Fan1a7e6252019-08-22 07:42:33 +000013#include <spl.h>
Peng Fanb5906342021-08-07 16:00:38 +080014#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +080015#include <asm/mach-imx/ahab.h>
Peng Fanb5906342021-08-07 16:00:38 +080016#endif
Peng Fanf1e0f9f2019-09-25 08:11:14 +000017
Peng Fan1a7e6252019-08-22 07:42:33 +000018static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image,
19 struct spl_load_info *info,
20 struct container_hdr *container,
21 int image_index,
Sean Anderson7d8d6132023-11-08 11:48:40 -050022 ulong container_offset)
Peng Fan1a7e6252019-08-22 07:42:33 +000023{
24 struct boot_img_t *images;
Sean Anderson7d8d6132023-11-08 11:48:40 -050025 ulong offset, overhead, size;
Peng Fan1a7e6252019-08-22 07:42:33 +000026
27 if (image_index > container->num_images) {
28 debug("Invalid image number\n");
29 return NULL;
30 }
31
32 images = (struct boot_img_t *)((u8 *)container +
33 sizeof(struct container_hdr));
34
Sean Andersonf97fc6d2023-11-08 11:48:39 -050035 if (!IS_ALIGNED(images[image_index].offset, info->bl_len)) {
Peng Fan1a7e6252019-08-22 07:42:33 +000036 printf("%s: image%d offset not aligned to %u\n",
37 __func__, image_index, info->bl_len);
38 return NULL;
39 }
40
Sean Anderson7d8d6132023-11-08 11:48:40 -050041 size = ALIGN(images[image_index].size, info->bl_len);
42 offset = images[image_index].offset + container_offset;
Peng Fan1a7e6252019-08-22 07:42:33 +000043
Sean Anderson7d8d6132023-11-08 11:48:40 -050044 debug("%s: container: %p offset: %lu size: %lu\n", __func__,
45 container, offset, size);
46 if (info->read(info, offset, size,
47 map_sysmem(images[image_index].dst - overhead,
48 images[image_index].size)) != 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 Andersonf97fc6d2023-11-08 11:48:39 -050068 size = ALIGN(CONTAINER_HDR_ALIGNMENT, info->bl_len);
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);
80 if (info->read(info, offset, size, container) != size) {
Nitin Gargf39c1f22023-06-15 18:09:22 +080081 ret = -EIO;
82 goto end;
83 }
Peng Fan1a7e6252019-08-22 07:42:33 +000084
Sean Andersonc5126682023-10-14 16:47:43 -040085 if (!valid_container_hdr(container)) {
Sean Anderson5d5c7bd2023-10-14 16:47:42 -040086 log_err("Wrong container header\n");
Nitin Gargf39c1f22023-06-15 18:09:22 +080087 ret = -ENOENT;
88 goto end;
Peng Fan1a7e6252019-08-22 07:42:33 +000089 }
90
91 if (!container->num_images) {
Sean Anderson5d5c7bd2023-10-14 16:47:42 -040092 log_err("Wrong container, no image found\n");
Nitin Gargf39c1f22023-06-15 18:09:22 +080093 ret = -ENOENT;
94 goto end;
Peng Fan1a7e6252019-08-22 07:42:33 +000095 }
96
97 length = container->length_lsb + (container->length_msb << 8);
98 debug("Container length %u\n", length);
99
100 if (length > CONTAINER_HDR_ALIGNMENT) {
Sean Andersonf97fc6d2023-11-08 11:48:39 -0500101 size = ALIGN(length, info->bl_len);
Peng Fan1a7e6252019-08-22 07:42:33 +0000102
Nitin Gargf39c1f22023-06-15 18:09:22 +0800103 free(container);
104 container = malloc(size);
105 if (!container)
106 return -ENOMEM;
Peng Fan1a7e6252019-08-22 07:42:33 +0000107
Sean Anderson7d8d6132023-11-08 11:48:40 -0500108 debug("%s: container: %p offset: %lu size: %u\n",
109 __func__, container, offset, size);
110 if (info->read(info, offset, size, container) != size) {
Nitin Gargf39c1f22023-06-15 18:09:22 +0800111 ret = -EIO;
112 goto end;
113 }
Peng Fan1a7e6252019-08-22 07:42:33 +0000114 }
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000115
116#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +0800117 ret = ahab_auth_cntr_hdr(container, length);
118 if (ret)
Nitin Gargf39c1f22023-06-15 18:09:22 +0800119 goto end_auth;
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000120#endif
Peng Fan1a7e6252019-08-22 07:42:33 +0000121
122 for (i = 0; i < container->num_images; i++) {
123 struct boot_img_t *image = read_auth_image(spl_image, info,
124 container, i,
Sean Anderson7d8d6132023-11-08 11:48:40 -0500125 offset);
Peng Fan1a7e6252019-08-22 07:42:33 +0000126
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000127 if (!image) {
128 ret = -EINVAL;
129 goto end_auth;
130 }
Peng Fan1a7e6252019-08-22 07:42:33 +0000131
132 if (i == 0) {
133 spl_image->load_addr = image->dst;
134 spl_image->entry_point = image->entry;
135 }
136 }
137
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000138end_auth:
139#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +0800140 ahab_auth_release();
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000141#endif
Nitin Gargf39c1f22023-06-15 18:09:22 +0800142
143end:
144 free(container);
145
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000146 return ret;
Peng Fan1a7e6252019-08-22 07:42:33 +0000147}
148
149int spl_load_imx_container(struct spl_image_info *spl_image,
Sean Anderson7d8d6132023-11-08 11:48:40 -0500150 struct spl_load_info *info, ulong offset)
Peng Fan1a7e6252019-08-22 07:42:33 +0000151{
Sean Anderson7d8d6132023-11-08 11:48:40 -0500152 return read_auth_container(spl_image, info, offset);
Peng Fan1a7e6252019-08-22 07:42:33 +0000153}