blob: e2a9e2b273282c287b5eb9830936dc00f646d6a8 [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
6#include <common.h>
Nitin Gargf39c1f22023-06-15 18:09:22 +08007#include <stdlib.h>
Peng Fan1a7e6252019-08-22 07:42:33 +00008#include <errno.h>
Simon Glass0f2af882020-05-10 11:40:05 -06009#include <log.h>
Peng Fan1a7e6252019-08-22 07:42:33 +000010#include <spl.h>
Ye Lieb101272021-08-07 16:00:37 +080011#include <asm/mach-imx/image.h>
Peng Fanb5906342021-08-07 16:00:38 +080012#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +080013#include <asm/mach-imx/ahab.h>
Peng Fanb5906342021-08-07 16:00:38 +080014#endif
Peng Fanf1e0f9f2019-09-25 08:11:14 +000015
Peng Fan1a7e6252019-08-22 07:42:33 +000016static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image,
17 struct spl_load_info *info,
18 struct container_hdr *container,
19 int image_index,
20 u32 container_sector)
21{
22 struct boot_img_t *images;
23 ulong sector;
24 u32 sectors;
25
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
34 if (images[image_index].offset % info->bl_len) {
35 printf("%s: image%d offset not aligned to %u\n",
36 __func__, image_index, info->bl_len);
37 return NULL;
38 }
39
40 sectors = roundup(images[image_index].size, info->bl_len) /
41 info->bl_len;
42 sector = images[image_index].offset / info->bl_len +
43 container_sector;
44
45 debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
46 container, sector, sectors);
47 if (info->read(info, sector, sectors,
48 (void *)images[image_index].entry) != sectors) {
49 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,
62 struct spl_load_info *info, ulong sector)
63{
64 struct container_hdr *container = NULL;
65 u16 length;
66 u32 sectors;
Peng Fanf1e0f9f2019-09-25 08:11:14 +000067 int i, size, ret = 0;
Peng Fan1a7e6252019-08-22 07:42:33 +000068
69 size = roundup(CONTAINER_HDR_ALIGNMENT, info->bl_len);
70 sectors = size / info->bl_len;
71
72 /*
73 * It will not override the ATF code, so safe to use it here,
74 * no need malloc
75 */
Nitin Gargf39c1f22023-06-15 18:09:22 +080076 container = malloc(size);
77 if (!container)
78 return -ENOMEM;
Peng Fan1a7e6252019-08-22 07:42:33 +000079
80 debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
81 container, sector, sectors);
Nitin Gargf39c1f22023-06-15 18:09:22 +080082 if (info->read(info, sector, sectors, container) != sectors) {
83 ret = -EIO;
84 goto end;
85 }
Peng Fan1a7e6252019-08-22 07:42:33 +000086
87 if (container->tag != 0x87 && container->version != 0x0) {
Nitin Gargf39c1f22023-06-15 18:09:22 +080088 printf("Wrong container header");
89 ret = -ENOENT;
90 goto end;
Peng Fan1a7e6252019-08-22 07:42:33 +000091 }
92
93 if (!container->num_images) {
Nitin Gargf39c1f22023-06-15 18:09:22 +080094 printf("Wrong container, no image found");
95 ret = -ENOENT;
96 goto end;
Peng Fan1a7e6252019-08-22 07:42:33 +000097 }
98
99 length = container->length_lsb + (container->length_msb << 8);
100 debug("Container length %u\n", length);
101
102 if (length > CONTAINER_HDR_ALIGNMENT) {
103 size = roundup(length, info->bl_len);
104 sectors = size / info->bl_len;
105
Nitin Gargf39c1f22023-06-15 18:09:22 +0800106 free(container);
107 container = malloc(size);
108 if (!container)
109 return -ENOMEM;
Peng Fan1a7e6252019-08-22 07:42:33 +0000110
111 debug("%s: container: %p sector: %lu sectors: %u\n",
112 __func__, container, sector, sectors);
113 if (info->read(info, sector, sectors, container) !=
Nitin Gargf39c1f22023-06-15 18:09:22 +0800114 sectors) {
115 ret = -EIO;
116 goto end;
117 }
Peng Fan1a7e6252019-08-22 07:42:33 +0000118 }
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000119
120#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +0800121 ret = ahab_auth_cntr_hdr(container, length);
122 if (ret)
Nitin Gargf39c1f22023-06-15 18:09:22 +0800123 goto end_auth;
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000124#endif
Peng Fan1a7e6252019-08-22 07:42:33 +0000125
126 for (i = 0; i < container->num_images; i++) {
127 struct boot_img_t *image = read_auth_image(spl_image, info,
128 container, i,
129 sector);
130
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000131 if (!image) {
132 ret = -EINVAL;
133 goto end_auth;
134 }
Peng Fan1a7e6252019-08-22 07:42:33 +0000135
136 if (i == 0) {
137 spl_image->load_addr = image->dst;
138 spl_image->entry_point = image->entry;
139 }
140 }
141
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000142end_auth:
143#ifdef CONFIG_AHAB_BOOT
Ye Li185af302023-06-15 18:09:23 +0800144 ahab_auth_release();
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000145#endif
Nitin Gargf39c1f22023-06-15 18:09:22 +0800146
147end:
148 free(container);
149
Peng Fanf1e0f9f2019-09-25 08:11:14 +0000150 return ret;
Peng Fan1a7e6252019-08-22 07:42:33 +0000151}
152
153int spl_load_imx_container(struct spl_image_info *spl_image,
154 struct spl_load_info *info, ulong sector)
155{
156 return read_auth_container(spl_image, info, sector);
157}