xref: /rk3399_rockchip-uboot/env/nowhere.c (revision 10427e2df5a90fdf95a3ef373e36c5dd49ba07ad)
1 /*
2  * (C) Copyright 2000-2010
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
6  * Andreas Heppel <aheppel@sysgo.de>
7 
8  * SPDX-License-Identifier:	GPL-2.0+
9  */
10 
11 #include <common.h>
12 #include <command.h>
13 #include <environment.h>
14 #include <linux/stddef.h>
15 #include <boot_rkimg.h>
16 #include <memalign.h>
17 
18 DECLARE_GLOBAL_DATA_PTR;
19 
20 #ifdef CONFIG_ENVF
21 /*
22  * example: ./tools/mkenvimage -s 0x8000 -p 0x0 -o envf.bin envf.txt
23  *
24  * - 0x8000: the value of CONFIG_ENV_SIZE.
25  * - env.txt: input file
26  */
27 #define ENVF_MAX_ENTRY		64
28 #define ENVF_PART		"envf"
29 #define ENVF_EMSG		"error: please use \"bootargs_envf\" but not " \
30 				"\"bootargs\" in CONFIG_ENVF_LIST and envf.bin"
31 static char *envf_entry[ENVF_MAX_ENTRY];
32 static u32 envf_num;
33 
34 static int envf_extract_list(void)
35 {
36 	char *tok, *p;
37 	u32 i = 0;
38 
39 	tok = strdup(CONFIG_ENVF_LIST);
40 	if (!tok)
41 		return -ENOMEM;
42 
43 	p = strtok(tok, " ");
44 	while (p && i < ENVF_MAX_ENTRY) {
45 		if (!strcmp(p, "bootargs")) {
46 			printf("%s\n", ENVF_EMSG);
47 			run_command("download", 0);
48 		}
49 		envf_entry[i++] = p;
50 		p = strtok(NULL, " ");
51 	}
52 
53 	envf_num = i;
54 
55 	return 0;
56 }
57 
58 /* allow failure, not stop boot */
59 static int envf_load(void)
60 {
61 	struct blk_desc *dev_desc;
62 	disk_partition_t part;
63 	env_t *envf;
64 	u32 blk_cnt;
65 	int ret = 0;
66 
67 	printf("ENVF: ");
68 
69 	dev_desc = rockchip_get_bootdev();
70 	if (!dev_desc) {
71 		printf("dev_desc null!\n");
72 		return 0;
73 	}
74 
75 	if (part_get_info_by_name(dev_desc, ENVF_PART, &part) < 0) {
76 		printf("no %s partition\n", ENVF_PART);
77 		return 0;
78 	}
79 
80 	blk_cnt = DIV_ROUND_UP(ENV_SIZE, part.blksz);
81 	envf = memalign(ARCH_DMA_MINALIGN, blk_cnt * part.blksz);
82 	if (!envf) {
83 		printf("no memory\n");
84 		return 0;
85 	}
86 
87 	if (blk_dread(dev_desc, part.start, blk_cnt, (void *)envf) != blk_cnt) {
88 		printf("io error\n");
89 		ret = -EIO;
90 		goto out;
91 	}
92 
93 	if (crc32(0, envf->data, ENV_SIZE) != envf->crc) {
94 		printf("!bad CRC\n");
95 		ret = -EINVAL;
96 		goto out;
97 	}
98 
99 	envf_extract_list();
100 
101 	if (!himport_r(&env_htab, (char *)envf->data, ENV_SIZE, '\0',
102 		       H_NOCLEAR, 0, envf_num, envf_entry))
103 		printf("himport error\n");
104 
105 	printf("OK\n");
106 
107 out:
108 	if (envf)
109 		free(envf);
110 
111 	return ret;
112 }
113 
114 static int envf_save(void)
115 {
116 	ALLOC_CACHE_ALIGN_BUFFER(env_t, envf, 1);
117 	struct blk_desc *dev_desc;
118 	disk_partition_t part;
119 	u32 blk_cnt;
120 	ssize_t	len;
121 	char *res;
122 
123 	dev_desc = rockchip_get_bootdev();
124 	if (!dev_desc) {
125 		printf("dev_desc null!\n");
126 		return -EINVAL;
127 	}
128 
129 	if (part_get_info_by_name(dev_desc, ENVF_PART, &part) < 0) {
130 		printf("envf: no partition\n");
131 		return -ENODEV;
132 	}
133 
134 	blk_cnt = DIV_ROUND_UP(ENV_SIZE, part.blksz);
135 	res = (char *)envf->data;
136 	len = hexport_r(&env_htab, '\0', H_MATCH_KEY | H_MATCH_IDENT,
137 			&res, ENV_SIZE, envf_num, envf_entry);
138 	if (len < 0) {
139 		printf("envf: hexpor errno: %d\n", errno);
140 		return -EINVAL;
141 	}
142 
143 	envf->crc = crc32(0, envf->data, ENV_SIZE);
144 	if (blk_dwrite(dev_desc, part.start, blk_cnt, (char *)envf) != blk_cnt) {
145 		printf("envf: io error\n");
146 		return -EIO;
147 	}
148 
149 	return 0;
150 }
151 #endif
152 
153 /*
154  * Because we only ever have the default environment available we must mark
155  * it as invalid.
156  */
157 static int env_nowhere_init(void)
158 {
159 	gd->env_addr	= (ulong)&default_environment[0];
160 	gd->env_valid	= ENV_INVALID;
161 
162 	return 0;
163 }
164 
165 U_BOOT_ENV_LOCATION(nowhere) = {
166 	.location	= ENVL_NOWHERE,
167 	.init		= env_nowhere_init,
168 #ifdef CONFIG_ENVF
169 	.load		= envf_load,
170 	.save		= env_save_ptr(envf_save),
171 	ENV_NAME("envf")
172 #else
173 	ENV_NAME("nowhere")
174 #endif
175 };
176