1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * (C) Copyright 2019 Rockchip Electronics Co., Ltd
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun #include <common.h>
7*4882a593Smuzhiyun #include <boot_rkimg.h>
8*4882a593Smuzhiyun #include <image.h>
9*4882a593Smuzhiyun #include <malloc.h>
10*4882a593Smuzhiyun #include <sysmem.h>
11*4882a593Smuzhiyun #include <asm/arch/fit.h>
12*4882a593Smuzhiyun #include <asm/arch/resource_img.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #define FIT_PLACEHOLDER_ADDR 0xffffff00
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun /*
19*4882a593Smuzhiyun * Must use args '-E -p' for mkimage to generate FIT image, 4K as max assumption.
20*4882a593Smuzhiyun */
21*4882a593Smuzhiyun #define FIT_FDT_MAX_SIZE SZ_4K
22*4882a593Smuzhiyun
fit_is_ext_type(const void * fit)23*4882a593Smuzhiyun static int fit_is_ext_type(const void *fit)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun return fdt_totalsize(fit) < FIT_FDT_MAX_SIZE;
26*4882a593Smuzhiyun }
27*4882a593Smuzhiyun
fit_is_signed(const void * fit,const void * sig_blob)28*4882a593Smuzhiyun static int fit_is_signed(const void *fit, const void *sig_blob)
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun return fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME) < 0 ? 0 : 1;
31*4882a593Smuzhiyun }
32*4882a593Smuzhiyun
fit_image_addr_is_placeholder(ulong addr)33*4882a593Smuzhiyun static inline int fit_image_addr_is_placeholder(ulong addr)
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun return (addr & 0xffffff00) == FIT_PLACEHOLDER_ADDR;
36*4882a593Smuzhiyun }
37*4882a593Smuzhiyun
fit_sig_require_conf(const void * fit,const void * sig_blob)38*4882a593Smuzhiyun static int fit_sig_require_conf(const void *fit, const void *sig_blob)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun const char *required;
41*4882a593Smuzhiyun int sig_node;
42*4882a593Smuzhiyun int noffset;
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun sig_node = fdt_subnode_offset(sig_blob, 0, FIT_SIG_NODENAME);
45*4882a593Smuzhiyun if (sig_node < 0)
46*4882a593Smuzhiyun return 0;
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun fdt_for_each_subnode(noffset, sig_blob, sig_node) {
49*4882a593Smuzhiyun required = fdt_getprop(sig_blob, noffset, "required", NULL);
50*4882a593Smuzhiyun if (required && !strcmp(required, "conf"))
51*4882a593Smuzhiyun return 1;
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun return 0;
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun
fit_default_conf_get_node(const void * fit,const char * prop_name)57*4882a593Smuzhiyun int fit_default_conf_get_node(const void *fit, const char *prop_name)
58*4882a593Smuzhiyun {
59*4882a593Smuzhiyun int conf_noffset;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun conf_noffset = fit_conf_get_node(fit, NULL); /* NULL for default conf */
62*4882a593Smuzhiyun if (conf_noffset < 0)
63*4882a593Smuzhiyun return conf_noffset;
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun return fit_conf_get_prop_node(fit, conf_noffset, prop_name);
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun
fix_image_set_addr(const void * fit,const char * prop_name,ulong old,ulong new)68*4882a593Smuzhiyun int fix_image_set_addr(const void *fit, const char *prop_name,
69*4882a593Smuzhiyun ulong old, ulong new)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun int noffset;
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun /* do not fix if verified-boot */
74*4882a593Smuzhiyun if (!fit_image_addr_is_placeholder(old) ||
75*4882a593Smuzhiyun fit_sig_require_conf(fit, gd_fdt_blob()))
76*4882a593Smuzhiyun return 0;
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun noffset = fit_default_conf_get_node(fit, prop_name);
79*4882a593Smuzhiyun if (noffset < 0)
80*4882a593Smuzhiyun return noffset;
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun /* optional */
83*4882a593Smuzhiyun fit_image_set_entry(fit, noffset, new);
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun return fit_image_set_load(fit, noffset, new);
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun
fdt_image_get_offset_size(const void * fit,const char * prop_name,int * offset,int * size)88*4882a593Smuzhiyun static int fdt_image_get_offset_size(const void *fit, const char *prop_name,
89*4882a593Smuzhiyun int *offset, int *size)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun int sz, offs;
92*4882a593Smuzhiyun int noffset;
93*4882a593Smuzhiyun int ret;
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun noffset = fit_default_conf_get_node(fit, prop_name);
96*4882a593Smuzhiyun if (noffset < 0)
97*4882a593Smuzhiyun return noffset;
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun ret = fit_image_get_data_size(fit, noffset, &sz);
100*4882a593Smuzhiyun if (ret)
101*4882a593Smuzhiyun return ret;
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun ret = fit_image_get_data_position(fit, noffset, &offs);
104*4882a593Smuzhiyun if (!ret)
105*4882a593Smuzhiyun offs -= fdt_totalsize(fit);
106*4882a593Smuzhiyun else
107*4882a593Smuzhiyun ret = fit_image_get_data_offset(fit, noffset, &offs);
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun *offset = offs;
110*4882a593Smuzhiyun *size = sz;
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun return ret;
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun
fdt_image_get_load(const void * fit,const char * prop_name,ulong * load)115*4882a593Smuzhiyun static int fdt_image_get_load(const void *fit, const char *prop_name,
116*4882a593Smuzhiyun ulong *load)
117*4882a593Smuzhiyun {
118*4882a593Smuzhiyun int noffset;
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun noffset = fit_default_conf_get_node(fit, prop_name);
121*4882a593Smuzhiyun if (noffset < 0)
122*4882a593Smuzhiyun return noffset;
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun return fit_image_get_load(fit, noffset, load);
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun
fit_image_get_param(const void * fit,const char * prop_name,ulong * load,int * offset,int * size)127*4882a593Smuzhiyun static int fit_image_get_param(const void *fit, const char *prop_name,
128*4882a593Smuzhiyun ulong *load, int *offset, int *size)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun int ret;
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun ret = fdt_image_get_offset_size(fit, prop_name, offset, size);
133*4882a593Smuzhiyun if (ret < 0)
134*4882a593Smuzhiyun return ret;
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun return fdt_image_get_load(fit, prop_name, load);
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun
fit_get_blob(struct blk_desc * dev_desc,disk_partition_t * out_part,bool verify)139*4882a593Smuzhiyun static void *fit_get_blob(struct blk_desc *dev_desc,
140*4882a593Smuzhiyun disk_partition_t *out_part,
141*4882a593Smuzhiyun bool verify)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun __maybe_unused int conf_noffset;
144*4882a593Smuzhiyun disk_partition_t part;
145*4882a593Smuzhiyun char *part_name = PART_BOOT;
146*4882a593Smuzhiyun void *fit, *fdt;
147*4882a593Smuzhiyun int blk_num;
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun #ifndef CONFIG_ANDROID_AB
150*4882a593Smuzhiyun if (rockchip_get_boot_mode() == BOOT_MODE_RECOVERY)
151*4882a593Smuzhiyun part_name = PART_RECOVERY;
152*4882a593Smuzhiyun #endif
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun if (part_get_info_by_name(dev_desc, part_name, &part) < 0) {
155*4882a593Smuzhiyun FIT_I("No %s partition\n", part_name);
156*4882a593Smuzhiyun return NULL;
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun *out_part = part;
160*4882a593Smuzhiyun blk_num = DIV_ROUND_UP(sizeof(struct fdt_header), dev_desc->blksz);
161*4882a593Smuzhiyun fdt = memalign(ARCH_DMA_MINALIGN, blk_num * dev_desc->blksz);
162*4882a593Smuzhiyun if (!fdt)
163*4882a593Smuzhiyun return NULL;
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun if (blk_dread(dev_desc, part.start, blk_num, fdt) != blk_num) {
166*4882a593Smuzhiyun debug("Failed to read fdt header\n");
167*4882a593Smuzhiyun goto fail;
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun if (fdt_check_header(fdt)) {
171*4882a593Smuzhiyun debug("No fdt header\n");
172*4882a593Smuzhiyun goto fail;
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun if (!fit_is_ext_type(fdt)) {
176*4882a593Smuzhiyun debug("Not external type\n");
177*4882a593Smuzhiyun goto fail;
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun blk_num = DIV_ROUND_UP(fdt_totalsize(fdt), dev_desc->blksz);
181*4882a593Smuzhiyun fit = memalign(ARCH_DMA_MINALIGN, blk_num * dev_desc->blksz);
182*4882a593Smuzhiyun if (!fit) {
183*4882a593Smuzhiyun debug("No memory\n");
184*4882a593Smuzhiyun goto fail;
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun if (blk_dread(dev_desc, part.start, blk_num, fit) != blk_num) {
188*4882a593Smuzhiyun free(fit);
189*4882a593Smuzhiyun debug("Failed to read fit blob\n");
190*4882a593Smuzhiyun goto fail;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun #ifdef CONFIG_FIT_SIGNATURE
194*4882a593Smuzhiyun if (!verify)
195*4882a593Smuzhiyun return fit;
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun conf_noffset = fit_conf_get_node(fit, NULL); /* NULL for default conf */
198*4882a593Smuzhiyun if (conf_noffset < 0)
199*4882a593Smuzhiyun goto fail;
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun printf("%s: ", fdt_get_name(fit, conf_noffset, NULL));
202*4882a593Smuzhiyun if (fit_config_verify(fit, conf_noffset)) {
203*4882a593Smuzhiyun puts("\n");
204*4882a593Smuzhiyun /* don't remove this failure handle */
205*4882a593Smuzhiyun run_command("download", 0);
206*4882a593Smuzhiyun hang();
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun puts("\n");
209*4882a593Smuzhiyun #endif
210*4882a593Smuzhiyun return fit;
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun fail:
213*4882a593Smuzhiyun free(fdt);
214*4882a593Smuzhiyun return NULL;
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun
fit_image_fixup_alloc(const void * fit,const char * prop_name,const char * addr_name,enum memblk_id mem)217*4882a593Smuzhiyun static int fit_image_fixup_alloc(const void *fit, const char *prop_name,
218*4882a593Smuzhiyun const char *addr_name, enum memblk_id mem)
219*4882a593Smuzhiyun {
220*4882a593Smuzhiyun ulong load, addr;
221*4882a593Smuzhiyun int offset, size = 0;
222*4882a593Smuzhiyun int ret;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun addr = env_get_ulong(addr_name, 16, 0);
225*4882a593Smuzhiyun if (!addr)
226*4882a593Smuzhiyun return -EINVAL;
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun ret = fit_image_get_param(fit, prop_name, &load, &offset, &size);
229*4882a593Smuzhiyun if (ret)
230*4882a593Smuzhiyun return (ret == -FDT_ERR_NOTFOUND) ? 0 : ret;
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun if (!size)
233*4882a593Smuzhiyun return 0;
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun ret = fix_image_set_addr(fit, prop_name, load, addr);
236*4882a593Smuzhiyun if (ret)
237*4882a593Smuzhiyun return ret;
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun if (!sysmem_alloc_base(mem, (phys_addr_t)addr,
240*4882a593Smuzhiyun ALIGN(size, RK_BLK_SIZE)))
241*4882a593Smuzhiyun return -ENOMEM;
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun return 0;
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun
fit_image_pre_process(const void * fit)246*4882a593Smuzhiyun int fit_image_pre_process(const void *fit)
247*4882a593Smuzhiyun {
248*4882a593Smuzhiyun int ret;
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun /* free for fit_image_fixup_alloc(FIT_FDT_PROP) to re-alloc */
251*4882a593Smuzhiyun if ((gd->flags & GD_FLG_KDTB_READY) && !gd->fdt_blob_kern)
252*4882a593Smuzhiyun sysmem_free((phys_addr_t)gd->fdt_blob);
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun ret = fit_image_fixup_alloc(fit, FIT_FDT_PROP,
255*4882a593Smuzhiyun "fdt_addr_r", MEM_FDT);
256*4882a593Smuzhiyun if (ret < 0)
257*4882a593Smuzhiyun return ret;
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun ret = fit_image_fixup_alloc(fit, FIT_KERNEL_PROP,
260*4882a593Smuzhiyun "kernel_addr_r", MEM_KERNEL);
261*4882a593Smuzhiyun if (ret < 0)
262*4882a593Smuzhiyun return ret;
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun return fit_image_fixup_alloc(fit, FIT_RAMDISK_PROP,
265*4882a593Smuzhiyun "ramdisk_addr_r", MEM_RAMDISK);
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun
fit_image_fail_process(const void * fit)268*4882a593Smuzhiyun int fit_image_fail_process(const void *fit)
269*4882a593Smuzhiyun {
270*4882a593Smuzhiyun ulong raddr, kaddr, faddr;
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun raddr = env_get_ulong("ramdisk_addr_r", 16, 0);
273*4882a593Smuzhiyun kaddr = env_get_ulong("kernel_addr_r", 16, 0);
274*4882a593Smuzhiyun faddr = env_get_ulong("fdt_addr_r", 16, 0);
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun sysmem_free((phys_addr_t)fit);
277*4882a593Smuzhiyun sysmem_free((phys_addr_t)raddr);
278*4882a593Smuzhiyun sysmem_free((phys_addr_t)kaddr);
279*4882a593Smuzhiyun sysmem_free((phys_addr_t)faddr);
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun return 0;
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun
fit_image_get_subnode(const void * fit,int noffset,const char * name)284*4882a593Smuzhiyun static int fit_image_get_subnode(const void *fit, int noffset, const char *name)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun int sub_noffset;
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun fdt_for_each_subnode(sub_noffset, fit, noffset) {
289*4882a593Smuzhiyun if (!strncmp(fit_get_name(fit, sub_noffset, NULL),
290*4882a593Smuzhiyun name, strlen(name)))
291*4882a593Smuzhiyun return sub_noffset;
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun return -ENOENT;
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
fit_image_load_one(const void * fit,struct blk_desc * dev_desc,disk_partition_t * part,char * prop_name,void * data,int check_hash)297*4882a593Smuzhiyun static int fit_image_load_one(const void *fit, struct blk_desc *dev_desc,
298*4882a593Smuzhiyun disk_partition_t *part, char *prop_name,
299*4882a593Smuzhiyun void *data, int check_hash)
300*4882a593Smuzhiyun {
301*4882a593Smuzhiyun u32 blk_num, blk_off;
302*4882a593Smuzhiyun int offset, size;
303*4882a593Smuzhiyun int noffset, ret;
304*4882a593Smuzhiyun char *msg = "";
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun ret = fdt_image_get_offset_size(fit, prop_name, &offset, &size);
307*4882a593Smuzhiyun if (ret)
308*4882a593Smuzhiyun return ret;
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun blk_off = (FIT_ALIGN(fdt_totalsize(fit)) + offset) / dev_desc->blksz;
311*4882a593Smuzhiyun blk_num = DIV_ROUND_UP(size, dev_desc->blksz);
312*4882a593Smuzhiyun if (blk_dread(dev_desc, part->start + blk_off, blk_num, data) != blk_num)
313*4882a593Smuzhiyun return -EIO;
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun if (check_hash) {
316*4882a593Smuzhiyun int hash_noffset;
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun noffset = fit_default_conf_get_node(fit, prop_name);
319*4882a593Smuzhiyun if (noffset < 0)
320*4882a593Smuzhiyun return noffset;
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun hash_noffset = fit_image_get_subnode(fit, noffset,
323*4882a593Smuzhiyun FIT_HASH_NODENAME);
324*4882a593Smuzhiyun if (hash_noffset < 0)
325*4882a593Smuzhiyun return hash_noffset;
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun printf("%s: ", fdt_get_name(fit, noffset, NULL));
328*4882a593Smuzhiyun ret = fit_image_check_hash(fit, hash_noffset, data, size, &msg);
329*4882a593Smuzhiyun if (ret)
330*4882a593Smuzhiyun return ret;
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun puts("+\n");
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun return 0;
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun /* Calculate what we really need */
fit_image_get_bootables_size(const void * fit)339*4882a593Smuzhiyun ulong fit_image_get_bootables_size(const void *fit)
340*4882a593Smuzhiyun {
341*4882a593Smuzhiyun ulong off[3] = { 0, 0, 0 };
342*4882a593Smuzhiyun ulong max_off, load;
343*4882a593Smuzhiyun int offset, size;
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun #if 0
346*4882a593Smuzhiyun if (!fit_get_totalsize(fit, &size))
347*4882a593Smuzhiyun return size;
348*4882a593Smuzhiyun #endif
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun if (!fit_image_get_param(fit, FIT_FDT_PROP, &load, &offset, &size))
351*4882a593Smuzhiyun off[0] = offset + FIT_ALIGN(size);
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun if (!fit_image_get_param(fit, FIT_KERNEL_PROP, &load, &offset, &size))
354*4882a593Smuzhiyun off[1] = offset + FIT_ALIGN(size);
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun if (!fit_image_get_param(fit, FIT_RAMDISK_PROP, &load, &offset, &size))
357*4882a593Smuzhiyun off[2] = offset + FIT_ALIGN(size);
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun max_off = max(off[0], off[1]);
360*4882a593Smuzhiyun max_off = max(max_off, off[2]);
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun return FIT_ALIGN(fdt_totalsize(fit)) + max_off;
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun
fit_image_load_bootables(ulong * size)365*4882a593Smuzhiyun void *fit_image_load_bootables(ulong *size)
366*4882a593Smuzhiyun {
367*4882a593Smuzhiyun struct blk_desc *dev_desc;
368*4882a593Smuzhiyun disk_partition_t part;
369*4882a593Smuzhiyun int blk_num;
370*4882a593Smuzhiyun void *fit;
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun dev_desc = rockchip_get_bootdev();
373*4882a593Smuzhiyun if (!dev_desc)
374*4882a593Smuzhiyun return NULL;
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun fit = fit_get_blob(dev_desc, &part, false);
377*4882a593Smuzhiyun if (!fit) {
378*4882a593Smuzhiyun FIT_I("No fit blob\n");
379*4882a593Smuzhiyun return NULL;
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun *size = fit_image_get_bootables_size(fit);
383*4882a593Smuzhiyun if (*size == 0) {
384*4882a593Smuzhiyun FIT_I("No bootable image\n");
385*4882a593Smuzhiyun return NULL;
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun blk_num = DIV_ROUND_UP(*size, dev_desc->blksz);
389*4882a593Smuzhiyun fit = sysmem_alloc(MEM_FIT, blk_num * dev_desc->blksz);
390*4882a593Smuzhiyun if (!fit)
391*4882a593Smuzhiyun return NULL;
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun if (blk_dread(dev_desc, part.start, blk_num, fit) != blk_num) {
394*4882a593Smuzhiyun FIT_I("Failed to load bootable images\n");
395*4882a593Smuzhiyun return NULL;
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun return fit;
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun
fit_msg(const void * fit)401*4882a593Smuzhiyun static void fit_msg(const void *fit)
402*4882a593Smuzhiyun {
403*4882a593Smuzhiyun FIT_I("%ssigned, %sconf required\n",
404*4882a593Smuzhiyun fit_is_signed(fit, gd_fdt_blob()) ? "" : "no ",
405*4882a593Smuzhiyun fit_sig_require_conf(fit, gd_fdt_blob()) ? "" : "no ");
406*4882a593Smuzhiyun }
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE
fit_image_init_resource(struct blk_desc * dev_desc)409*4882a593Smuzhiyun ulong fit_image_init_resource(struct blk_desc *dev_desc)
410*4882a593Smuzhiyun {
411*4882a593Smuzhiyun disk_partition_t part;
412*4882a593Smuzhiyun void *fit, *buf;
413*4882a593Smuzhiyun int offset, size;
414*4882a593Smuzhiyun int ret = 0;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun if (!dev_desc)
417*4882a593Smuzhiyun return -ENODEV;
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun fit = fit_get_blob(dev_desc, &part, true);
420*4882a593Smuzhiyun if (!fit)
421*4882a593Smuzhiyun return -EAGAIN;
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun ret = fdt_image_get_offset_size(fit, FIT_MULTI_PROP, &offset, &size);
424*4882a593Smuzhiyun if (ret)
425*4882a593Smuzhiyun return -EINVAL;
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun buf = memalign(ARCH_DMA_MINALIGN, ALIGN(size, dev_desc->blksz));
428*4882a593Smuzhiyun if (!buf)
429*4882a593Smuzhiyun return -ENOMEM;
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun printf("RESC: '%s', blk@0x%08lx\n", part.name,
432*4882a593Smuzhiyun part.start + ((FIT_ALIGN(fdt_totalsize(fit)) + offset) / dev_desc->blksz));
433*4882a593Smuzhiyun ret = fit_image_load_one(fit, dev_desc, &part, FIT_MULTI_PROP, buf, 1);
434*4882a593Smuzhiyun if (ret)
435*4882a593Smuzhiyun return ret;
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun ret = resource_setup_ram_list(dev_desc, buf);
438*4882a593Smuzhiyun if (ret) {
439*4882a593Smuzhiyun FIT_I("Failed to setup resource ram list, ret=%d\n", ret);
440*4882a593Smuzhiyun free(fit);
441*4882a593Smuzhiyun return ret;
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun fit_msg(fit);
445*4882a593Smuzhiyun free(fit);
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun return 0;
448*4882a593Smuzhiyun }
449*4882a593Smuzhiyun #else
fit_image_read_dtb(void * fdt_addr)450*4882a593Smuzhiyun int fit_image_read_dtb(void *fdt_addr)
451*4882a593Smuzhiyun {
452*4882a593Smuzhiyun struct blk_desc *dev_desc;
453*4882a593Smuzhiyun disk_partition_t part;
454*4882a593Smuzhiyun void *fit;
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun dev_desc = rockchip_get_bootdev();
457*4882a593Smuzhiyun if (!dev_desc) {
458*4882a593Smuzhiyun FIT_I("No dev_desc!\n");
459*4882a593Smuzhiyun return -ENODEV;;
460*4882a593Smuzhiyun }
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun fit = fit_get_blob(dev_desc, &part, true);
463*4882a593Smuzhiyun if (!fit)
464*4882a593Smuzhiyun return -EINVAL;
465*4882a593Smuzhiyun
466*4882a593Smuzhiyun fit_msg(fit);
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun return fit_image_load_one(fit, dev_desc, &part, FIT_FDT_PROP,
469*4882a593Smuzhiyun (void *)fdt_addr, 1);
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun #endif
472