xref: /rk3399_rockchip-uboot/cmd/bootrkp.c (revision e72b912575f8808965903814ed22e640c4faef4e)
1a0e58cf2SKever Yang /*
2a0e58cf2SKever Yang  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3a0e58cf2SKever Yang  *
4a0e58cf2SKever Yang  * SPDX-License-Identifier:     GPL-2.0+
5a0e58cf2SKever Yang  */
6a0e58cf2SKever Yang 
7a0e58cf2SKever Yang #include <common.h>
8*e72b9125SJoseph Chen #include <attestation_key.h>
9*e72b9125SJoseph Chen #include <bootm.h>
1014768307SJoseph Chen #include <boot_rkimg.h>
1114768307SJoseph Chen #include <keymaster.h>
12*e72b9125SJoseph Chen #include <console.h>
13*e72b9125SJoseph Chen #include <image.h>
146caa0333SKever Yang #include <malloc.h>
15*e72b9125SJoseph Chen #include <sysmem.h>
16*e72b9125SJoseph Chen #include <linux/libfdt.h>
17*e72b9125SJoseph Chen #include <asm/arch/hotkey.h>
18*e72b9125SJoseph Chen #include <asm/arch/resource_img.h>
19*e72b9125SJoseph Chen #include <asm/arch/boot_mode.h>
20a0e58cf2SKever Yang 
21*e72b9125SJoseph Chen DECLARE_GLOBAL_DATA_PTR;
22*e72b9125SJoseph Chen 
23*e72b9125SJoseph Chen #ifdef CONFIG_ROCKCHIP_CRC
24*e72b9125SJoseph Chen #define tole(x) cpu_to_le32(x)
25*e72b9125SJoseph Chen 
26*e72b9125SJoseph Chen /* Table of CRC-32's of all single-byte values (made by make_crc_table) */
27*e72b9125SJoseph Chen static const uint32_t crc_table[256] = {
28*e72b9125SJoseph Chen 	tole(0x00000000L), tole(0x04c10db7L), tole(0x09821b6eL), tole(0x0d4316d9L),
29*e72b9125SJoseph Chen 	tole(0x130436dcL), tole(0x17c53b6bL), tole(0x1a862db2L), tole(0x1e472005L),
30*e72b9125SJoseph Chen 	tole(0x26086db8L), tole(0x22c9600fL), tole(0x2f8a76d6L), tole(0x2b4b7b61L),
31*e72b9125SJoseph Chen 	tole(0x350c5b64L), tole(0x31cd56d3L), tole(0x3c8e400aL), tole(0x384f4dbdL),
32*e72b9125SJoseph Chen 	tole(0x4c10db70L), tole(0x48d1d6c7L), tole(0x4592c01eL), tole(0x4153cda9L),
33*e72b9125SJoseph Chen 	tole(0x5f14edacL), tole(0x5bd5e01bL), tole(0x5696f6c2L), tole(0x5257fb75L),
34*e72b9125SJoseph Chen 	tole(0x6a18b6c8L), tole(0x6ed9bb7fL), tole(0x639aada6L), tole(0x675ba011L),
35*e72b9125SJoseph Chen 	tole(0x791c8014L), tole(0x7ddd8da3L), tole(0x709e9b7aL), tole(0x745f96cdL),
36*e72b9125SJoseph Chen 	tole(0x9821b6e0L), tole(0x9ce0bb57L), tole(0x91a3ad8eL), tole(0x9562a039L),
37*e72b9125SJoseph Chen 	tole(0x8b25803cL), tole(0x8fe48d8bL), tole(0x82a79b52L), tole(0x866696e5L),
38*e72b9125SJoseph Chen 	tole(0xbe29db58L), tole(0xbae8d6efL), tole(0xb7abc036L), tole(0xb36acd81L),
39*e72b9125SJoseph Chen 	tole(0xad2ded84L), tole(0xa9ece033L), tole(0xa4aff6eaL), tole(0xa06efb5dL),
40*e72b9125SJoseph Chen 	tole(0xd4316d90L), tole(0xd0f06027L), tole(0xddb376feL), tole(0xd9727b49L),
41*e72b9125SJoseph Chen 	tole(0xc7355b4cL), tole(0xc3f456fbL), tole(0xceb74022L), tole(0xca764d95L),
42*e72b9125SJoseph Chen 	tole(0xf2390028L), tole(0xf6f80d9fL), tole(0xfbbb1b46L), tole(0xff7a16f1L),
43*e72b9125SJoseph Chen 	tole(0xe13d36f4L), tole(0xe5fc3b43L), tole(0xe8bf2d9aL), tole(0xec7e202dL),
44*e72b9125SJoseph Chen 	tole(0x34826077L), tole(0x30436dc0L), tole(0x3d007b19L), tole(0x39c176aeL),
45*e72b9125SJoseph Chen 	tole(0x278656abL), tole(0x23475b1cL), tole(0x2e044dc5L), tole(0x2ac54072L),
46*e72b9125SJoseph Chen 	tole(0x128a0dcfL), tole(0x164b0078L), tole(0x1b0816a1L), tole(0x1fc91b16L),
47*e72b9125SJoseph Chen 	tole(0x018e3b13L), tole(0x054f36a4L), tole(0x080c207dL), tole(0x0ccd2dcaL),
48*e72b9125SJoseph Chen 	tole(0x7892bb07L), tole(0x7c53b6b0L), tole(0x7110a069L), tole(0x75d1addeL),
49*e72b9125SJoseph Chen 	tole(0x6b968ddbL), tole(0x6f57806cL), tole(0x621496b5L), tole(0x66d59b02L),
50*e72b9125SJoseph Chen 	tole(0x5e9ad6bfL), tole(0x5a5bdb08L), tole(0x5718cdd1L), tole(0x53d9c066L),
51*e72b9125SJoseph Chen 	tole(0x4d9ee063L), tole(0x495fedd4L), tole(0x441cfb0dL), tole(0x40ddf6baL),
52*e72b9125SJoseph Chen 	tole(0xaca3d697L), tole(0xa862db20L), tole(0xa521cdf9L), tole(0xa1e0c04eL),
53*e72b9125SJoseph Chen 	tole(0xbfa7e04bL), tole(0xbb66edfcL), tole(0xb625fb25L), tole(0xb2e4f692L),
54*e72b9125SJoseph Chen 	tole(0x8aabbb2fL), tole(0x8e6ab698L), tole(0x8329a041L), tole(0x87e8adf6L),
55*e72b9125SJoseph Chen 	tole(0x99af8df3L), tole(0x9d6e8044L), tole(0x902d969dL), tole(0x94ec9b2aL),
56*e72b9125SJoseph Chen 	tole(0xe0b30de7L), tole(0xe4720050L), tole(0xe9311689L), tole(0xedf01b3eL),
57*e72b9125SJoseph Chen 	tole(0xf3b73b3bL), tole(0xf776368cL), tole(0xfa352055L), tole(0xfef42de2L),
58*e72b9125SJoseph Chen 	tole(0xc6bb605fL), tole(0xc27a6de8L), tole(0xcf397b31L), tole(0xcbf87686L),
59*e72b9125SJoseph Chen 	tole(0xd5bf5683L), tole(0xd17e5b34L), tole(0xdc3d4dedL), tole(0xd8fc405aL),
60*e72b9125SJoseph Chen 	tole(0x6904c0eeL), tole(0x6dc5cd59L), tole(0x6086db80L), tole(0x6447d637L),
61*e72b9125SJoseph Chen 	tole(0x7a00f632L), tole(0x7ec1fb85L), tole(0x7382ed5cL), tole(0x7743e0ebL),
62*e72b9125SJoseph Chen 	tole(0x4f0cad56L), tole(0x4bcda0e1L), tole(0x468eb638L), tole(0x424fbb8fL),
63*e72b9125SJoseph Chen 	tole(0x5c089b8aL), tole(0x58c9963dL), tole(0x558a80e4L), tole(0x514b8d53L),
64*e72b9125SJoseph Chen 	tole(0x25141b9eL), tole(0x21d51629L), tole(0x2c9600f0L), tole(0x28570d47L),
65*e72b9125SJoseph Chen 	tole(0x36102d42L), tole(0x32d120f5L), tole(0x3f92362cL), tole(0x3b533b9bL),
66*e72b9125SJoseph Chen 	tole(0x031c7626L), tole(0x07dd7b91L), tole(0x0a9e6d48L), tole(0x0e5f60ffL),
67*e72b9125SJoseph Chen 	tole(0x101840faL), tole(0x14d94d4dL), tole(0x199a5b94L), tole(0x1d5b5623L),
68*e72b9125SJoseph Chen 	tole(0xf125760eL), tole(0xf5e47bb9L), tole(0xf8a76d60L), tole(0xfc6660d7L),
69*e72b9125SJoseph Chen 	tole(0xe22140d2L), tole(0xe6e04d65L), tole(0xeba35bbcL), tole(0xef62560bL),
70*e72b9125SJoseph Chen 	tole(0xd72d1bb6L), tole(0xd3ec1601L), tole(0xdeaf00d8L), tole(0xda6e0d6fL),
71*e72b9125SJoseph Chen 	tole(0xc4292d6aL), tole(0xc0e820ddL), tole(0xcdab3604L), tole(0xc96a3bb3L),
72*e72b9125SJoseph Chen 	tole(0xbd35ad7eL), tole(0xb9f4a0c9L), tole(0xb4b7b610L), tole(0xb076bba7L),
73*e72b9125SJoseph Chen 	tole(0xae319ba2L), tole(0xaaf09615L), tole(0xa7b380ccL), tole(0xa3728d7bL),
74*e72b9125SJoseph Chen 	tole(0x9b3dc0c6L), tole(0x9ffccd71L), tole(0x92bfdba8L), tole(0x967ed61fL),
75*e72b9125SJoseph Chen 	tole(0x8839f61aL), tole(0x8cf8fbadL), tole(0x81bbed74L), tole(0x857ae0c3L),
76*e72b9125SJoseph Chen 	tole(0x5d86a099L), tole(0x5947ad2eL), tole(0x5404bbf7L), tole(0x50c5b640L),
77*e72b9125SJoseph Chen 	tole(0x4e829645L), tole(0x4a439bf2L), tole(0x47008d2bL), tole(0x43c1809cL),
78*e72b9125SJoseph Chen 	tole(0x7b8ecd21L), tole(0x7f4fc096L), tole(0x720cd64fL), tole(0x76cddbf8L),
79*e72b9125SJoseph Chen 	tole(0x688afbfdL), tole(0x6c4bf64aL), tole(0x6108e093L), tole(0x65c9ed24L),
80*e72b9125SJoseph Chen 	tole(0x11967be9L), tole(0x1557765eL), tole(0x18146087L), tole(0x1cd56d30L),
81*e72b9125SJoseph Chen 	tole(0x02924d35L), tole(0x06534082L), tole(0x0b10565bL), tole(0x0fd15becL),
82*e72b9125SJoseph Chen 	tole(0x379e1651L), tole(0x335f1be6L), tole(0x3e1c0d3fL), tole(0x3add0088L),
83*e72b9125SJoseph Chen 	tole(0x249a208dL), tole(0x205b2d3aL), tole(0x2d183be3L), tole(0x29d93654L),
84*e72b9125SJoseph Chen 	tole(0xc5a71679L), tole(0xc1661bceL), tole(0xcc250d17L), tole(0xc8e400a0L),
85*e72b9125SJoseph Chen 	tole(0xd6a320a5L), tole(0xd2622d12L), tole(0xdf213bcbL), tole(0xdbe0367cL),
86*e72b9125SJoseph Chen 	tole(0xe3af7bc1L), tole(0xe76e7676L), tole(0xea2d60afL), tole(0xeeec6d18L),
87*e72b9125SJoseph Chen 	tole(0xf0ab4d1dL), tole(0xf46a40aaL), tole(0xf9295673L), tole(0xfde85bc4L),
88*e72b9125SJoseph Chen 	tole(0x89b7cd09L), tole(0x8d76c0beL), tole(0x8035d667L), tole(0x84f4dbd0L),
89*e72b9125SJoseph Chen 	tole(0x9ab3fbd5L), tole(0x9e72f662L), tole(0x9331e0bbL), tole(0x97f0ed0cL),
90*e72b9125SJoseph Chen 	tole(0xafbfa0b1L), tole(0xab7ead06L), tole(0xa63dbbdfL), tole(0xa2fcb668L),
91*e72b9125SJoseph Chen 	tole(0xbcbb966dL), tole(0xb87a9bdaL), tole(0xb5398d03L), tole(0xb1f880b4L)
92*e72b9125SJoseph Chen };
93*e72b9125SJoseph Chen 
94*e72b9125SJoseph Chen #define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc << 8)
95*e72b9125SJoseph Chen 
96*e72b9125SJoseph Chen static uint32_t crc32_rk(uint32_t crc, const unsigned char *s, uint32_t len)
97a0e58cf2SKever Yang {
98*e72b9125SJoseph Chen 	const uint32_t *tab;
99*e72b9125SJoseph Chen 
100*e72b9125SJoseph Chen 	tab = crc_table;
101*e72b9125SJoseph Chen 	crc = cpu_to_le32(crc);
102*e72b9125SJoseph Chen 
103*e72b9125SJoseph Chen 	do {
104*e72b9125SJoseph Chen 		DO_CRC(*s++);
105*e72b9125SJoseph Chen 	} while (--len);
106*e72b9125SJoseph Chen 
107*e72b9125SJoseph Chen 	return le32_to_cpu(crc);
108*e72b9125SJoseph Chen }
109*e72b9125SJoseph Chen 
110*e72b9125SJoseph Chen #undef DO_CRC
111*e72b9125SJoseph Chen 
112*e72b9125SJoseph Chen static u32 crc32_verify(unsigned char *data, u32 size)
113*e72b9125SJoseph Chen {
114*e72b9125SJoseph Chen 	u32 crc_check = 0, crc_calc = 0;
115*e72b9125SJoseph Chen 	int i = 0;
116*e72b9125SJoseph Chen 
117*e72b9125SJoseph Chen 	if (size <= 4)
118*e72b9125SJoseph Chen 		return 0;
119*e72b9125SJoseph Chen 
120*e72b9125SJoseph Chen 	size -= 4;
121*e72b9125SJoseph Chen 	for (i = 3; i >= 0; i--)
122*e72b9125SJoseph Chen 		crc_check = (crc_check << 8) + (*(data + size + i));
123*e72b9125SJoseph Chen 
124*e72b9125SJoseph Chen 	crc_calc = crc32_rk(0, data, size);
125*e72b9125SJoseph Chen 
126*e72b9125SJoseph Chen 	return (crc_calc == crc_check) ? crc_check : 0;
127*e72b9125SJoseph Chen }
128*e72b9125SJoseph Chen #endif
129*e72b9125SJoseph Chen 
130*e72b9125SJoseph Chen #if !defined(CONFIG_ARM64)
131*e72b9125SJoseph Chen #ifdef CONFIG_LMB
132*e72b9125SJoseph Chen static void boot_start_lmb(bootm_headers_t *images)
133*e72b9125SJoseph Chen {
134*e72b9125SJoseph Chen 	lmb_init(&images->lmb);
135*e72b9125SJoseph Chen #ifdef CONFIG_NR_DRAM_BANKS
136*e72b9125SJoseph Chen 	int i;
137*e72b9125SJoseph Chen 
138*e72b9125SJoseph Chen 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
139*e72b9125SJoseph Chen 		lmb_add(&images->lmb, gd->bd->bi_dram[i].start,
140*e72b9125SJoseph Chen 			gd->bd->bi_dram[i].size);
141*e72b9125SJoseph Chen 	}
142*e72b9125SJoseph Chen #else
143*e72b9125SJoseph Chen 	ulong		mem_start;
144*e72b9125SJoseph Chen 	phys_size_t	mem_size;
145*e72b9125SJoseph Chen 
146*e72b9125SJoseph Chen 	mem_start = env_get_bootm_low();
147*e72b9125SJoseph Chen 	mem_size = env_get_bootm_size();
148*e72b9125SJoseph Chen 	lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size);
149*e72b9125SJoseph Chen #endif
150*e72b9125SJoseph Chen 	arch_lmb_reserve(&images->lmb);
151*e72b9125SJoseph Chen 	board_lmb_reserve(&images->lmb);
152*e72b9125SJoseph Chen }
153*e72b9125SJoseph Chen #else
154*e72b9125SJoseph Chen static inline void boot_start_lmb(bootm_headers_t *images) { }
155*e72b9125SJoseph Chen #endif
156*e72b9125SJoseph Chen 
157*e72b9125SJoseph Chen static void boot_lmb_init(bootm_headers_t *images)
158*e72b9125SJoseph Chen {
159*e72b9125SJoseph Chen 	boot_start_lmb(images);
160*e72b9125SJoseph Chen 	images->state = BOOTM_STATE_OS_GO;
161*e72b9125SJoseph Chen }
162*e72b9125SJoseph Chen #endif
163*e72b9125SJoseph Chen 
164*e72b9125SJoseph Chen static void fdt_ramdisk_skip_relocation(void)
165*e72b9125SJoseph Chen {
166*e72b9125SJoseph Chen 	char *ramdisk_high = env_get("initrd_high");
167*e72b9125SJoseph Chen 	char *fdt_high = env_get("fdt_high");
168*e72b9125SJoseph Chen 
169*e72b9125SJoseph Chen 	if (!fdt_high) {
170*e72b9125SJoseph Chen 		env_set_hex("fdt_high", -1UL);
171*e72b9125SJoseph Chen 		printf("Fdt ");
172*e72b9125SJoseph Chen 	}
173*e72b9125SJoseph Chen 
174*e72b9125SJoseph Chen 	if (!ramdisk_high) {
175*e72b9125SJoseph Chen 		env_set_hex("initrd_high", -1UL);
176*e72b9125SJoseph Chen 		printf("Ramdisk ");
177*e72b9125SJoseph Chen 	}
178*e72b9125SJoseph Chen 
179*e72b9125SJoseph Chen 	if (!fdt_high || !ramdisk_high)
180*e72b9125SJoseph Chen 		printf("skip relocation\n");
181*e72b9125SJoseph Chen }
182*e72b9125SJoseph Chen 
183*e72b9125SJoseph Chen /*
184*e72b9125SJoseph Chen  * non-OTA packaged kernel.img & boot.img return the image size on success,
185*e72b9125SJoseph Chen  * and a negative value on error.
186*e72b9125SJoseph Chen  */
187*e72b9125SJoseph Chen static int read_rockchip_image(struct blk_desc *dev_desc,
188*e72b9125SJoseph Chen 			       disk_partition_t *part, void *dst)
189*e72b9125SJoseph Chen {
190*e72b9125SJoseph Chen 	struct rockchip_image *img;
191*e72b9125SJoseph Chen 	int header_len = 8;
192*e72b9125SJoseph Chen 	int cnt, ret;
193*e72b9125SJoseph Chen #ifdef CONFIG_ROCKCHIP_CRC
194*e72b9125SJoseph Chen 	u32 crc32;
195*e72b9125SJoseph Chen #endif
196*e72b9125SJoseph Chen 
197*e72b9125SJoseph Chen 	img = memalign(ARCH_DMA_MINALIGN, RK_BLK_SIZE);
198*e72b9125SJoseph Chen 	if (!img)
199*e72b9125SJoseph Chen 		return -ENOMEM;
200*e72b9125SJoseph Chen 
201*e72b9125SJoseph Chen 	/* read first block with header imformation */
202*e72b9125SJoseph Chen 	ret = blk_dread(dev_desc, part->start, 1, img);
203*e72b9125SJoseph Chen 	if (ret != 1) {
204*e72b9125SJoseph Chen 		ret = -EIO;
205*e72b9125SJoseph Chen 		goto err;
206*e72b9125SJoseph Chen 	}
207*e72b9125SJoseph Chen 
208*e72b9125SJoseph Chen 	if (img->tag != TAG_KERNEL) {
209*e72b9125SJoseph Chen 		printf("Invalid %s image tag(0x%x)\n", part->name, img->tag);
210*e72b9125SJoseph Chen 		ret = -EINVAL;
211*e72b9125SJoseph Chen 		goto err;
212*e72b9125SJoseph Chen 	}
213*e72b9125SJoseph Chen 
214*e72b9125SJoseph Chen 	/*
215*e72b9125SJoseph Chen 	 * read the rest blks
216*e72b9125SJoseph Chen 	 * total size = image size + 8 bytes header + 4 bytes crc32
217*e72b9125SJoseph Chen 	 */
218*e72b9125SJoseph Chen 	cnt = DIV_ROUND_UP(img->size + 8 + 4, RK_BLK_SIZE);
219*e72b9125SJoseph Chen 	if (!sysmem_alloc_base_by_name((const char *)part->name,
220*e72b9125SJoseph Chen 				       (phys_addr_t)dst,
221*e72b9125SJoseph Chen 				       cnt * dev_desc->blksz)) {
222*e72b9125SJoseph Chen 		ret = -ENXIO;
223*e72b9125SJoseph Chen 		goto err;
224*e72b9125SJoseph Chen 	}
225*e72b9125SJoseph Chen 
226*e72b9125SJoseph Chen 	memcpy(dst, img->image, RK_BLK_SIZE - header_len);
227*e72b9125SJoseph Chen 	ret = blk_dread(dev_desc, part->start + 1, cnt - 1,
228*e72b9125SJoseph Chen 			dst + RK_BLK_SIZE - header_len);
229*e72b9125SJoseph Chen 	if (ret != (cnt - 1)) {
230*e72b9125SJoseph Chen 		printf("Failed to read %s part, ret=%d\n", part->name, ret);
231*e72b9125SJoseph Chen 		ret = -EIO;
232*e72b9125SJoseph Chen 	} else {
233*e72b9125SJoseph Chen 		ret = img->size;
234*e72b9125SJoseph Chen 	}
235*e72b9125SJoseph Chen 
236*e72b9125SJoseph Chen #ifdef CONFIG_ROCKCHIP_CRC
237*e72b9125SJoseph Chen 	printf("%s image rk crc32 verify... ", part->name);
238*e72b9125SJoseph Chen 	crc32 = crc32_verify((uchar *)(ulong)dst, img->size + 4);
239*e72b9125SJoseph Chen 	if (!crc32) {
240*e72b9125SJoseph Chen 		printf("fail!\n");
241*e72b9125SJoseph Chen 		ret = -EINVAL;
242*e72b9125SJoseph Chen 	} else {
243*e72b9125SJoseph Chen 		printf("okay.\n");
244*e72b9125SJoseph Chen 	}
245*e72b9125SJoseph Chen #endif
246*e72b9125SJoseph Chen 
247*e72b9125SJoseph Chen err:
248*e72b9125SJoseph Chen 	free(img);
249*e72b9125SJoseph Chen 	return ret;
250*e72b9125SJoseph Chen }
251*e72b9125SJoseph Chen 
252*e72b9125SJoseph Chen static int boot_rockchip_image(struct blk_desc *dev_desc,
253*e72b9125SJoseph Chen 			       disk_partition_t *boot_part)
254*e72b9125SJoseph Chen {
255*e72b9125SJoseph Chen 	disk_partition_t kernel_part;
256*e72b9125SJoseph Chen 	ulong ramdisk_addr_r;
257*e72b9125SJoseph Chen 	ulong kernel_addr_r;
258*e72b9125SJoseph Chen 	ulong fdt_addr_r;
259*e72b9125SJoseph Chen 	int ramdisk_size;
260*e72b9125SJoseph Chen 	int kernel_size;
261*e72b9125SJoseph Chen 	int fdt_size;
262*e72b9125SJoseph Chen 	int ret;
263*e72b9125SJoseph Chen 
264*e72b9125SJoseph Chen 	printf("\n## Booting Rockchip Format Image\n");
265*e72b9125SJoseph Chen 
266*e72b9125SJoseph Chen 	ramdisk_addr_r = env_get_ulong("ramdisk_addr_r", 16, 0);
267*e72b9125SJoseph Chen 	kernel_addr_r = env_get_ulong("kernel_addr_r", 16, 0);
268*e72b9125SJoseph Chen 	fdt_addr_r = env_get_ulong("fdt_addr_r", 16, 0);
269*e72b9125SJoseph Chen 
270*e72b9125SJoseph Chen 	ret = part_get_info_by_name(dev_desc, PART_KERNEL, &kernel_part);
271*e72b9125SJoseph Chen 	if (ret < 0) {
272*e72b9125SJoseph Chen 		printf("Could not find kernel partition, ret=%d\n", ret);
273*e72b9125SJoseph Chen 		return -EINVAL;
274*e72b9125SJoseph Chen 	}
275*e72b9125SJoseph Chen 
276*e72b9125SJoseph Chen 	kernel_size = read_rockchip_image(dev_desc, &kernel_part,
277*e72b9125SJoseph Chen 					  (void *)kernel_addr_r);
278*e72b9125SJoseph Chen 	if (kernel_size < 0) {
279*e72b9125SJoseph Chen 		printf("Failed to read kernel image, ret=%d\n", ret);
280*e72b9125SJoseph Chen 		return -EINVAL;
281*e72b9125SJoseph Chen 	}
282*e72b9125SJoseph Chen 
283*e72b9125SJoseph Chen 	ramdisk_size = read_rockchip_image(dev_desc, boot_part,
284*e72b9125SJoseph Chen 					   (void *)ramdisk_addr_r);
285*e72b9125SJoseph Chen 	if (ramdisk_size < 0)
286*e72b9125SJoseph Chen 		ramdisk_size = 0;
287*e72b9125SJoseph Chen 
288*e72b9125SJoseph Chen 	if (gd->fdt_blob != (void *)fdt_addr_r) {
289*e72b9125SJoseph Chen 		fdt_size = rockchip_read_dtb_file((void *)fdt_addr_r);
290*e72b9125SJoseph Chen 		if (fdt_size < 0) {
291*e72b9125SJoseph Chen 			printf("Failed to read fdt, ret=%d\n", fdt_size);
292*e72b9125SJoseph Chen 			return -EINVAL;
293*e72b9125SJoseph Chen 		}
294*e72b9125SJoseph Chen 	}
295*e72b9125SJoseph Chen 
296*e72b9125SJoseph Chen 	printf("fdt	 @ 0x%08lx (0x%08x)\n", fdt_addr_r, fdt_totalsize(fdt_addr_r));
297*e72b9125SJoseph Chen 	printf("kernel   @ 0x%08lx (0x%08x)\n", kernel_addr_r, kernel_size);
298*e72b9125SJoseph Chen 	printf("ramdisk  @ 0x%08lx (0x%08x)\n", ramdisk_addr_r, ramdisk_size);
299*e72b9125SJoseph Chen 
300*e72b9125SJoseph Chen 	fdt_ramdisk_skip_relocation();
301*e72b9125SJoseph Chen 	hotkey_run(HK_SYSMEM);
302*e72b9125SJoseph Chen 	sysmem_overflow_check();
303*e72b9125SJoseph Chen 
304*e72b9125SJoseph Chen #if defined(CONFIG_ARM64)
305*e72b9125SJoseph Chen 	char cmdbuf[64];
306*e72b9125SJoseph Chen 
307*e72b9125SJoseph Chen 	snprintf(cmdbuf, 64, "booti 0x%lx 0x%lx:0x%x 0x%lx",
308*e72b9125SJoseph Chen 		 kernel_addr_r, ramdisk_addr_r, ramdisk_size, fdt_addr_r);
309*e72b9125SJoseph Chen 	run_command(cmdbuf, 0);
310*e72b9125SJoseph Chen #else
311*e72b9125SJoseph Chen 	/* We asume it's always zImage on 32-bit platform */
312*e72b9125SJoseph Chen 	ulong kaddr_c = env_get_ulong("kernel_addr_c", 16, 0);
313*e72b9125SJoseph Chen 	ulong kaddr_r, kaddr, ksize;
314*e72b9125SJoseph Chen 
315*e72b9125SJoseph Chen 	if (kernel_addr_r && !kaddr_c) {
316*e72b9125SJoseph Chen 		kaddr_c = kernel_addr_r;
317*e72b9125SJoseph Chen 		kaddr_r = CONFIG_SYS_SDRAM_BASE;
318*e72b9125SJoseph Chen 	}
319*e72b9125SJoseph Chen 
320*e72b9125SJoseph Chen 	if (!sysmem_free((phys_addr_t)kaddr_c)) {
321*e72b9125SJoseph Chen 		kaddr = kaddr_r;
322*e72b9125SJoseph Chen 		ksize = kernel_size * 100 / 45 ; /* Ratio: 45% */
323*e72b9125SJoseph Chen 		ksize = ALIGN(ksize, dev_desc->blksz);
324*e72b9125SJoseph Chen 		if (!sysmem_alloc_base(MEMBLK_ID_UNCOMP_KERNEL,
325*e72b9125SJoseph Chen 				       (phys_addr_t)kaddr, ksize))
326*e72b9125SJoseph Chen 			return -ENOMEM;
327*e72b9125SJoseph Chen 	}
328*e72b9125SJoseph Chen 
329*e72b9125SJoseph Chen 	hotkey_run(HK_SYSMEM);
330*e72b9125SJoseph Chen 	sysmem_overflow_check();
331*e72b9125SJoseph Chen 
332*e72b9125SJoseph Chen 	boot_lmb_init(&images);
333*e72b9125SJoseph Chen 	images.ep = kernel_addr_r;
334*e72b9125SJoseph Chen 	images.initrd_start = ramdisk_addr_r;
335*e72b9125SJoseph Chen 	images.initrd_end = ramdisk_addr_r + ramdisk_size;
336*e72b9125SJoseph Chen 	images.ft_addr = (void *)fdt_addr_r;
337*e72b9125SJoseph Chen 	images.ft_len = fdt_totalsize(fdt_addr_r);
338*e72b9125SJoseph Chen 	do_bootm_linux(0, 0, NULL, &images);
339*e72b9125SJoseph Chen #endif
340*e72b9125SJoseph Chen 
341*e72b9125SJoseph Chen 	return 0;
342*e72b9125SJoseph Chen }
343*e72b9125SJoseph Chen 
344*e72b9125SJoseph Chen static int do_boot_rockchip(cmd_tbl_t *cmdtp, int flag,
345*e72b9125SJoseph Chen 			    int argc, char *const argv[])
346*e72b9125SJoseph Chen {
347*e72b9125SJoseph Chen 	char *part_name = PART_BOOT;
348a0e58cf2SKever Yang 	struct blk_desc *dev_desc;
349*e72b9125SJoseph Chen 	disk_partition_t part;
350*e72b9125SJoseph Chen 	int ret;
351a0e58cf2SKever Yang 
352a0e58cf2SKever Yang 	dev_desc = rockchip_get_bootdev();
3536651d4c0SJason Zhu 	if (!dev_desc) {
354*e72b9125SJoseph Chen 		printf("dev_desc is NULL!\n");
3554701d790SAndy Yan 		return CMD_RET_FAILURE;
3566651d4c0SJason Zhu 	}
35791c73fb4Sqiujian 
358c2ba77d9SJian Qiu #ifdef CONFIG_ANDROID_KEYMASTER_CA
35991c73fb4Sqiujian 	/* load attestation key from misc partition. */
360*e72b9125SJoseph Chen 	ret = part_get_info_by_name(dev_desc, PART_MISC, &part);
36191c73fb4Sqiujian 	if (ret < 0)
362*e72b9125SJoseph Chen 		printf("Could not find misc partition\n");
36391c73fb4Sqiujian 	else
364*e72b9125SJoseph Chen 		load_attestation_key(dev_desc, &part);
36591c73fb4Sqiujian #endif
36691c73fb4Sqiujian 
36765413a00SJian Qiu #ifdef CONFIG_FASTBOOT_OEM_UNLOCK
3689e68721bSqiujian 	/* read oem unlock status and attach to bootargs */
36914768307SJoseph Chen 	char oem_unlock[30] = {0};
3709e68721bSqiujian 	TEEC_Result result;
37114768307SJoseph Chen 	uint8_t unlock = 0;
37214768307SJoseph Chen 
3739e68721bSqiujian 	result = trusty_read_oem_unlock(&unlock);
3749e68721bSqiujian 	if (result) {
375*e72b9125SJoseph Chen 		printf("Failed to read oem unlock status, ret=%d\n", result);
3769e68721bSqiujian 	} else {
37714768307SJoseph Chen 		snprintf(oem_unlock, sizeof(oem_unlock),
37814768307SJoseph Chen 			 "androidboot.oem_unlocked=%d", unlock);
3799e68721bSqiujian 		env_update("bootargs", oem_unlock);
3809e68721bSqiujian 	}
3819e68721bSqiujian #endif
382*e72b9125SJoseph Chen 	if (rockchip_get_boot_mode() == BOOT_MODE_RECOVERY)
383*e72b9125SJoseph Chen 		part_name = PART_RECOVERY;
3849e68721bSqiujian 
385*e72b9125SJoseph Chen 	ret = part_get_info_by_name(dev_desc, part_name, &part);
38614768307SJoseph Chen 	if (ret < 0) {
387*e72b9125SJoseph Chen 		printf("Could not find %s part\n", part.name);
38814768307SJoseph Chen 		return CMD_RET_FAILURE;
38914768307SJoseph Chen 	}
390a0e58cf2SKever Yang 
391*e72b9125SJoseph Chen 	return boot_rockchip_image(dev_desc, &part) ? CMD_RET_FAILURE : 0;
392a0e58cf2SKever Yang }
393a0e58cf2SKever Yang 
394a0e58cf2SKever Yang U_BOOT_CMD(
395*e72b9125SJoseph Chen 	bootrkp,  1,     1,      do_boot_rockchip,
39632af749aSKever Yang 	"Boot Linux Image from rockchip image type",
39732af749aSKever Yang 	"kernel.img: zImage/Image\n"
39832af749aSKever Yang 	"boot.img: ramdisk\n"
39932af749aSKever Yang 	"resource.img: dtb, u-boot logo, kernel logo"
400a0e58cf2SKever Yang );
401