xref: /rk3399_rockchip-uboot/env/env.c (revision ac358beb85362fb2fac47aaec40a7e1bca49656c)
1 /*
2  * Copyright (C) 2017 Google, Inc
3  * Written by Simon Glass <sjg@chromium.org>
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7 
8 #include <common.h>
9 #include <environment.h>
10 
11 DECLARE_GLOBAL_DATA_PTR;
12 
13 static struct env_driver *env_driver_lookup(enum env_location loc)
14 {
15 	struct env_driver *drv;
16 	const int n_ents = ll_entry_count(struct env_driver, env_driver);
17 	struct env_driver *entry;
18 
19 	drv = ll_entry_start(struct env_driver, env_driver);
20 	for (entry = drv; entry != drv + n_ents; entry++) {
21 		if (loc == entry->location)
22 			return entry;
23 	}
24 
25 	/* Not found */
26 	return NULL;
27 }
28 
29 static enum env_location env_get_default_location(void)
30 {
31 	if IS_ENABLED(CONFIG_ENV_IS_IN_DATAFLASH)
32 		return ENVL_DATAFLASH;
33 	else if IS_ENABLED(CONFIG_ENV_IS_IN_EEPROM)
34 		return ENVL_EEPROM;
35 	else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT)
36 		return ENVL_FAT;
37 	else if IS_ENABLED(CONFIG_ENV_IS_IN_FLASH)
38 		return ENVL_FLASH;
39 	else if IS_ENABLED(CONFIG_ENV_IS_IN_MMC)
40 		return ENVL_MMC;
41 	else if IS_ENABLED(CONFIG_ENV_IS_IN_NAND)
42 		return ENVL_NAND;
43 	else if IS_ENABLED(CONFIG_ENV_IS_IN_NVRAM)
44 		return ENVL_NVRAM;
45 	else if IS_ENABLED(CONFIG_ENV_IS_IN_REMOTE)
46 		return ENVL_REMOTE;
47 	else if IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH)
48 		return ENVL_SPI_FLASH;
49 	else if IS_ENABLED(CONFIG_ENV_IS_IN_UBI)
50 		return ENVL_UBI;
51 	else if IS_ENABLED(CONFIG_ENV_IS_NOWHERE)
52 		return ENVL_NOWHERE;
53 	else
54 		return ENVL_UNKNOWN;
55 }
56 
57 struct env_driver *env_driver_lookup_default(void)
58 {
59 	enum env_location loc = env_get_default_location();
60 	struct env_driver *drv;
61 
62 	drv = env_driver_lookup(loc);
63 	if (!drv) {
64 		debug("%s: No environment driver for location %d\n", __func__,
65 		      loc);
66 		return NULL;
67 	}
68 
69 	return drv;
70 }
71 
72 int env_get_char_new(int index)
73 {
74 	struct env_driver *drv = env_driver_lookup_default();
75 	int ret;
76 
77 	if (!drv)
78 		return -ENODEV;
79 	if (!drv->get_char)
80 		return *(uchar *)(gd->env_addr + index);
81 	ret = drv->get_char(index);
82 	if (ret < 0) {
83 		debug("%s: Environment failed to load (err=%d)\n",
84 		      __func__, ret);
85 	}
86 
87 	return ret;
88 }
89 
90 int env_load(void)
91 {
92 	struct env_driver *drv = env_driver_lookup_default();
93 	int ret = 0;
94 
95 	if (!drv)
96 		return -ENODEV;
97 	if (!drv->load)
98 		return 0;
99 	drv->load();  /* TODO(sjg@chromium.org): Make this return an error */
100 	if (ret) {
101 		debug("%s: Environment failed to load (err=%d)\n", __func__,
102 		      ret);
103 		return ret;
104 	}
105 
106 	return 0;
107 }
108 
109 int env_save(void)
110 {
111 	struct env_driver *drv = env_driver_lookup_default();
112 	int ret;
113 
114 	if (!drv)
115 		return -ENODEV;
116 	if (!drv->save)
117 		return -ENOSYS;
118 	ret = drv->save();
119 	if (ret) {
120 		debug("%s: Environment failed to save (err=%d)\n", __func__,
121 		      ret);
122 		return ret;
123 	}
124 
125 	return 0;
126 }
127 
128 int env_init_new(void)
129 {
130 	struct env_driver *drv = env_driver_lookup_default();
131 	int ret = -ENOENT;
132 
133 	if (!drv)
134 		return -ENODEV;
135 	if (drv->init)
136 		ret = drv->init();
137 	if (ret == -ENOENT) {
138 		gd->env_addr = (ulong)&default_environment[0];
139 		gd->env_valid = 0;
140 
141 		return 0;
142 	} else if (ret) {
143 		debug("%s: Environment failed to init (err=%d)\n", __func__,
144 		      ret);
145 		return ret;
146 	}
147 
148 	return 0;
149 }
150 
151 unsigned char env_get_char_spec(int index)
152 {
153 	return *(uchar *)(gd->env_addr + index);
154 }
155 
156 void env_relocate_spec(void)
157 {
158 	env_load();
159 }
160 
161 int saveenv(void)
162 {
163 	return env_save();
164 }
165 
166 int env_init(void)
167 {
168 	return env_init_new();
169 }
170