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