xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/rk_meta.c (revision d1efb02a55a89ce032a0da5302f2e9e91e925d25)
1 /* SPDX-License-Identifier:     GPL-2.0+ */
2 /*
3  * (C) Copyright 2022 Rockchip Electronics Co., Ltd
4  *
5  */
6 
7 #include <common.h>
8 #include <boot_rkimg.h>
9 #include <crc.h>
10 #include <errno.h>
11 #include <fdt_support.h>
12 #include <image.h>
13 #include <spl.h>
14 #include <asm/arch/rk_meta.h>
15 
16 static char *cmdline;
17 
18 int spl_load_meta(struct spl_image_info *spl_image, struct spl_load_info *info)
19 {
20 	const char *part_name = PART_META;
21 	disk_partition_t part_info;
22 	struct meta_head meta;
23 	struct meta_head *meta_p;
24 	struct cmdline_info *cmd;
25 	ulong sector;
26 	char *data;
27 
28 	if (part_get_info_by_name(info->dev, part_name, &part_info) <= 0) {
29 		debug("%s: no partition\n", __func__);
30 		return -EINVAL;
31 	}
32 	sector = part_info.start;
33 
34 	memset(&meta, 0, sizeof(struct meta_head));
35 	if (info->read(info, sector, 1, &meta) != 1) {
36 		debug("%s: Failed to read header\n", __func__);
37 		return -EIO;
38 	}
39 
40 	if (meta.tag != RK_META) {
41 		debug("Invalid meta tag is %x.\n", meta.tag);
42 		return -EINVAL;
43 	}
44 
45 	if (meta.crc32 != crc32(0, (const unsigned char *)&meta, sizeof(struct meta_head) - 4 - 4)) {
46 		debug("Invalid meta crc32.\n");
47 		return -EINVAL;
48 	}
49 
50 	data = (char *)meta.load;
51 	printf("Meta: 0x%08x - 0x%08x\n", meta.load, meta.load + meta.size);
52 	if (info->read(info, sector, meta.size / 512, data) != (meta.size / 512)) {
53 		debug("%s: Failed to read header\n", __func__);
54 		return -EIO;
55 	}
56 
57 	meta_p = (struct meta_head *)meta.load;
58 
59 	cmd = (struct cmdline_info *)(meta_p->load + CMDLINE_OFFSET);
60 	if (cmd->tag == RK_CMDLINE) {
61 		if (cmd->crc32 == crc32(0, (const unsigned char *)cmd, sizeof(struct cmdline_info) - 4))
62 			cmdline = (char *)cmd->data;
63 	}
64 
65 	meta_p->meta_flags = META_READ_DONE_FLAG;
66 	flush_cache(meta_p->load, meta_p->size);
67 
68 	return 0;
69 }
70 
71 void rk_meta_bootargs_append(void *fdt)
72 {
73 	if (!cmdline || (!fdt || fdt_check_header(fdt)))
74 		return;
75 
76 	fdt_bootargs_append(fdt, cmdline);
77 }
78