blob: c29cb15f55e3adff0cded027426cb19e15126e0e [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>
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,
21 u32 container_sector)
22{
23 struct boot_img_t *images;
24 ulong sector;
25 u32 sectors;
26
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
35 if (images[image_index].offset % info->bl_len) {
36 printf("%s: image%d offset not aligned to %u\n",
37 __func__, image_index, info->bl_len);
38 return NULL;
39 }
40
41 sectors = roundup(images[image_index].size, info->bl_len) /
42 info->bl_len;
43 sector = images[image_index].offset / info->bl_len +
44 container_sector;
45
46 debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
47 container, sector, sectors);
48 if (info->read(info, sector, sectors,
Sean Anderson3960b712023-10-14 16:47:40 -040049 (void *)images[image_index].dst) != sectors) {
Peng Fan1a7e6252019-08-22 07:42:33 +000050 printf("%s wrong\n", __func__);
51 return NULL;
52 }
Peng Fanf1e0f9f2019-09-25 08:11:14 +000053
54#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +080055 if (ahab_verify_cntr_image(&images[image_index], image_index))
Peng Fanf1e0f9f2019-09-25 08:11:14 +000056 return NULL;
Peng Fanf1e0f9f2019-09-25 08:11:14 +000057#endif
Peng Fan1a7e6252019-08-22 07:42:33 +000058
59 return &images[image_index];
60}
61
62static int read_auth_container(struct spl_image_info *spl_image,
63 struct spl_load_info *info, ulong sector)
64{
65 struct container_hdr *container = NULL;
66 u16 length;
67 u32 sectors;
Peng Fanf1e0f9f2019-09-25 08:11:14 +000068 int i, size, ret = 0;
Peng Fan1a7e6252019-08-22 07:42:33 +000069
70 size = roundup(CONTAINER_HDR_ALIGNMENT, info->bl_len);
71 sectors = size / info->bl_len;
72
73 /*
74 * It will not override the ATF code, so safe to use it here,
75 * no need malloc
76 */
Nitin Gargf39c1f22023-06-15 18:09:22 +080077 container = malloc(size);
78 if (!container)
79 return -ENOMEM;
Peng Fan1a7e6252019-08-22 07:42:33 +000080
81 debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
82 container, sector, sectors);
Nitin Gargf39c1f22023-06-15 18:09:22 +080083 if (info->read(info, sector, sectors, container) != sectors) {
84 ret = -EIO;
85 goto end;
86 }
Peng Fan1a7e6252019-08-22 07:42:33 +000087
Sean Andersonc5126682023-10-14 16:47:43 -040088 if (!valid_container_hdr(container)) {
Sean Anderson5d5c7bd2023-10-14 16:47:42 -040089 log_err("Wrong container header\n");
Nitin Gargf39c1f22023-06-15 18:09:22 +080090 ret = -ENOENT;
91 goto end;
Peng Fan1a7e6252019-08-22 07:42:33 +000092 }
93
94 if (!container->num_images) {
Sean Anderson5d5c7bd2023-10-14 16:47:42 -040095 log_err("Wrong container, no image found\n");
Nitin Gargf39c1f22023-06-15 18:09:22 +080096 ret = -ENOENT;
97 goto end;
Peng Fan1a7e6252019-08-22 07:42:33 +000098 }
99
100 length = container->length_lsb + (container->length_msb << 8);
101 debug("Container length %u\n", length);
102
103 if (length > CONTAINER_HDR_ALIGNMENT) {
104 size = roundup(length, info->bl_len);
105 sectors = size / info->bl_len;
106
Nitin Gargf39c1f22023-06-15 18:09:22 +0800107 free(container);
108 container = malloc(size);
109 if (!container)
110 return -ENOMEM;
Peng Fan1a7e6252019-08-22 07:42:33 +0000111
112 debug("%s: container: %p sector: %lu sectors: %u\n",
113 __func__, container, sector, sectors);
114 if (info->read(info, sector, sectors, container) !=
Nitin Gargf39c1f22023-06-15 18:09:22 +0800115 sectors) {
116 ret = -EIO;
117 goto end;
118 }
Peng Fan1a7e6252019-08-22 07:42:33 +0000119 }
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000120
121#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +0800122 ret = ahab_auth_cntr_hdr(container, length);
123 if (ret)
Nitin Gargf39c1f22023-06-15 18:09:22 +0800124 goto end_auth;
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000125#endif
Peng Fan1a7e6252019-08-22 07:42:33 +0000126
127 for (i = 0; i < container->num_images; i++) {
128 struct boot_img_t *image = read_auth_image(spl_image, info,
129 container, i,
130 sector);
131
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000132 if (!image) {
133 ret = -EINVAL;
134 goto end_auth;
135 }
Peng Fan1a7e6252019-08-22 07:42:33 +0000136
137 if (i == 0) {
138 spl_image->load_addr = image->dst;
139 spl_image->entry_point = image->entry;
140 }
141 }
142
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000143end_auth:
144#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +0800145 ahab_auth_release();
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000146#endif
Nitin Gargf39c1f22023-06-15 18:09:22 +0800147
148end:
149 free(container);
150
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000151 return ret;
Peng Fan1a7e6252019-08-22 07:42:33 +0000152}
153
154int spl_load_imx_container(struct spl_image_info *spl_image,
155 struct spl_load_info *info, ulong sector)
156{
157 return read_auth_container(spl_image, info, sector);
158}