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