blob: 127802f5cb7769957a21876e39280ddd8c5b01be [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,
22 u32 container_sector)
23{
24 struct boot_img_t *images;
25 ulong sector;
26 u32 sectors;
27
28 if (image_index > container->num_images) {
29 debug("Invalid image number\n");
30 return NULL;
31 }
32
33 images = (struct boot_img_t *)((u8 *)container +
34 sizeof(struct container_hdr));
35
36 if (images[image_index].offset % info->bl_len) {
37 printf("%s: image%d offset not aligned to %u\n",
38 __func__, image_index, info->bl_len);
39 return NULL;
40 }
41
42 sectors = roundup(images[image_index].size, info->bl_len) /
43 info->bl_len;
44 sector = images[image_index].offset / info->bl_len +
45 container_sector;
46
47 debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
48 container, sector, sectors);
49 if (info->read(info, sector, sectors,
Sean Anderson5ff77722023-10-14 16:47:55 -040050 map_sysmem(images[image_index].dst,
51 images[image_index].size)) != sectors) {
Peng Fan1a7e6252019-08-22 07:42:33 +000052 printf("%s wrong\n", __func__);
53 return NULL;
54 }
Peng Fanf1e0f9f2019-09-25 08:11:14 +000055
56#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +080057 if (ahab_verify_cntr_image(&images[image_index], image_index))
Peng Fanf1e0f9f2019-09-25 08:11:14 +000058 return NULL;
Peng Fanf1e0f9f2019-09-25 08:11:14 +000059#endif
Peng Fan1a7e6252019-08-22 07:42:33 +000060
61 return &images[image_index];
62}
63
64static int read_auth_container(struct spl_image_info *spl_image,
65 struct spl_load_info *info, ulong sector)
66{
67 struct container_hdr *container = NULL;
68 u16 length;
69 u32 sectors;
Peng Fanf1e0f9f2019-09-25 08:11:14 +000070 int i, size, ret = 0;
Peng Fan1a7e6252019-08-22 07:42:33 +000071
72 size = roundup(CONTAINER_HDR_ALIGNMENT, info->bl_len);
73 sectors = size / info->bl_len;
74
75 /*
76 * It will not override the ATF code, so safe to use it here,
77 * no need malloc
78 */
Nitin Gargf39c1f22023-06-15 18:09:22 +080079 container = malloc(size);
80 if (!container)
81 return -ENOMEM;
Peng Fan1a7e6252019-08-22 07:42:33 +000082
83 debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
84 container, sector, sectors);
Nitin Gargf39c1f22023-06-15 18:09:22 +080085 if (info->read(info, sector, sectors, container) != sectors) {
86 ret = -EIO;
87 goto end;
88 }
Peng Fan1a7e6252019-08-22 07:42:33 +000089
Sean Andersonc5126682023-10-14 16:47:43 -040090 if (!valid_container_hdr(container)) {
Sean Anderson5d5c7bd2023-10-14 16:47:42 -040091 log_err("Wrong container header\n");
Nitin Gargf39c1f22023-06-15 18:09:22 +080092 ret = -ENOENT;
93 goto end;
Peng Fan1a7e6252019-08-22 07:42:33 +000094 }
95
96 if (!container->num_images) {
Sean Anderson5d5c7bd2023-10-14 16:47:42 -040097 log_err("Wrong container, no image found\n");
Nitin Gargf39c1f22023-06-15 18:09:22 +080098 ret = -ENOENT;
99 goto end;
Peng Fan1a7e6252019-08-22 07:42:33 +0000100 }
101
102 length = container->length_lsb + (container->length_msb << 8);
103 debug("Container length %u\n", length);
104
105 if (length > CONTAINER_HDR_ALIGNMENT) {
106 size = roundup(length, info->bl_len);
107 sectors = size / info->bl_len;
108
Nitin Gargf39c1f22023-06-15 18:09:22 +0800109 free(container);
110 container = malloc(size);
111 if (!container)
112 return -ENOMEM;
Peng Fan1a7e6252019-08-22 07:42:33 +0000113
114 debug("%s: container: %p sector: %lu sectors: %u\n",
115 __func__, container, sector, sectors);
116 if (info->read(info, sector, sectors, container) !=
Nitin Gargf39c1f22023-06-15 18:09:22 +0800117 sectors) {
118 ret = -EIO;
119 goto end;
120 }
Peng Fan1a7e6252019-08-22 07:42:33 +0000121 }
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000122
123#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +0800124 ret = ahab_auth_cntr_hdr(container, length);
125 if (ret)
Nitin Gargf39c1f22023-06-15 18:09:22 +0800126 goto end_auth;
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000127#endif
Peng Fan1a7e6252019-08-22 07:42:33 +0000128
129 for (i = 0; i < container->num_images; i++) {
130 struct boot_img_t *image = read_auth_image(spl_image, info,
131 container, i,
132 sector);
133
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000134 if (!image) {
135 ret = -EINVAL;
136 goto end_auth;
137 }
Peng Fan1a7e6252019-08-22 07:42:33 +0000138
139 if (i == 0) {
140 spl_image->load_addr = image->dst;
141 spl_image->entry_point = image->entry;
142 }
143 }
144
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000145end_auth:
146#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +0800147 ahab_auth_release();
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000148#endif
Nitin Gargf39c1f22023-06-15 18:09:22 +0800149
150end:
151 free(container);
152
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000153 return ret;
Peng Fan1a7e6252019-08-22 07:42:33 +0000154}
155
156int spl_load_imx_container(struct spl_image_info *spl_image,
157 struct spl_load_info *info, ulong sector)
158{
159 return read_auth_container(spl_image, info, sector);
160}