xref: /openbmc/u-boot/env/env.c (revision 1087a794)
1c9d728ddSSimon Glass /*
2c9d728ddSSimon Glass  * Copyright (C) 2017 Google, Inc
3c9d728ddSSimon Glass  * Written by Simon Glass <sjg@chromium.org>
4c9d728ddSSimon Glass  *
5c9d728ddSSimon Glass  * SPDX-License-Identifier:     GPL-2.0+
6c9d728ddSSimon Glass  */
7c9d728ddSSimon Glass 
8c9d728ddSSimon Glass #include <common.h>
9c9d728ddSSimon Glass #include <environment.h>
10c9d728ddSSimon Glass 
11c9d728ddSSimon Glass DECLARE_GLOBAL_DATA_PTR;
12c9d728ddSSimon Glass 
13c9d728ddSSimon Glass static struct env_driver *env_driver_lookup(enum env_location loc)
14c9d728ddSSimon Glass {
15c9d728ddSSimon Glass 	struct env_driver *drv;
16c9d728ddSSimon Glass 	const int n_ents = ll_entry_count(struct env_driver, env_driver);
17c9d728ddSSimon Glass 	struct env_driver *entry;
18c9d728ddSSimon Glass 
19c9d728ddSSimon Glass 	drv = ll_entry_start(struct env_driver, env_driver);
20c9d728ddSSimon Glass 	for (entry = drv; entry != drv + n_ents; entry++) {
21c9d728ddSSimon Glass 		if (loc == entry->location)
22c9d728ddSSimon Glass 			return entry;
23c9d728ddSSimon Glass 	}
24c9d728ddSSimon Glass 
25c9d728ddSSimon Glass 	/* Not found */
26c9d728ddSSimon Glass 	return NULL;
27c9d728ddSSimon Glass }
28c9d728ddSSimon Glass 
29c9d728ddSSimon Glass static enum env_location env_get_default_location(void)
30c9d728ddSSimon Glass {
317b7341d7STuomas Tynkkynen 	if IS_ENABLED(CONFIG_ENV_IS_IN_EEPROM)
32c9d728ddSSimon Glass 		return ENVL_EEPROM;
33c9d728ddSSimon Glass 	else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT)
34c9d728ddSSimon Glass 		return ENVL_FAT;
35*1087a794SJorge Ramirez-Ortiz 	else if IS_ENABLED(CONFIG_ENV_IS_IN_EXT4)
36*1087a794SJorge Ramirez-Ortiz 		return ENVL_EXT4;
37c9d728ddSSimon Glass 	else if IS_ENABLED(CONFIG_ENV_IS_IN_FLASH)
38c9d728ddSSimon Glass 		return ENVL_FLASH;
39c9d728ddSSimon Glass 	else if IS_ENABLED(CONFIG_ENV_IS_IN_MMC)
40c9d728ddSSimon Glass 		return ENVL_MMC;
41c9d728ddSSimon Glass 	else if IS_ENABLED(CONFIG_ENV_IS_IN_NAND)
42c9d728ddSSimon Glass 		return ENVL_NAND;
43c9d728ddSSimon Glass 	else if IS_ENABLED(CONFIG_ENV_IS_IN_NVRAM)
44c9d728ddSSimon Glass 		return ENVL_NVRAM;
45c9d728ddSSimon Glass 	else if IS_ENABLED(CONFIG_ENV_IS_IN_REMOTE)
46c9d728ddSSimon Glass 		return ENVL_REMOTE;
47c9d728ddSSimon Glass 	else if IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH)
48c9d728ddSSimon Glass 		return ENVL_SPI_FLASH;
49c9d728ddSSimon Glass 	else if IS_ENABLED(CONFIG_ENV_IS_IN_UBI)
50c9d728ddSSimon Glass 		return ENVL_UBI;
51c9d728ddSSimon Glass 	else if IS_ENABLED(CONFIG_ENV_IS_NOWHERE)
52c9d728ddSSimon Glass 		return ENVL_NOWHERE;
53c9d728ddSSimon Glass 	else
54c9d728ddSSimon Glass 		return ENVL_UNKNOWN;
55c9d728ddSSimon Glass }
56c9d728ddSSimon Glass 
57ac358bebSSimon Glass struct env_driver *env_driver_lookup_default(void)
58c9d728ddSSimon Glass {
59c9d728ddSSimon Glass 	enum env_location loc = env_get_default_location();
60c9d728ddSSimon Glass 	struct env_driver *drv;
61c9d728ddSSimon Glass 
62c9d728ddSSimon Glass 	drv = env_driver_lookup(loc);
63c9d728ddSSimon Glass 	if (!drv) {
64c9d728ddSSimon Glass 		debug("%s: No environment driver for location %d\n", __func__,
65c9d728ddSSimon Glass 		      loc);
66c9d728ddSSimon Glass 		return NULL;
67c9d728ddSSimon Glass 	}
68c9d728ddSSimon Glass 
69c9d728ddSSimon Glass 	return drv;
70c9d728ddSSimon Glass }
71c9d728ddSSimon Glass 
72a69d0f60SSimon Glass int env_get_char(int index)
73c9d728ddSSimon Glass {
74c9d728ddSSimon Glass 	struct env_driver *drv = env_driver_lookup_default();
75c9d728ddSSimon Glass 	int ret;
76c9d728ddSSimon Glass 
772d7cb5b4SSimon Glass 	if (gd->env_valid == ENV_INVALID)
78a69d0f60SSimon Glass 		return default_environment[index];
79c9d728ddSSimon Glass 	if (!drv)
80c9d728ddSSimon Glass 		return -ENODEV;
81c9d728ddSSimon Glass 	if (!drv->get_char)
82c9d728ddSSimon Glass 		return *(uchar *)(gd->env_addr + index);
83c9d728ddSSimon Glass 	ret = drv->get_char(index);
84c9d728ddSSimon Glass 	if (ret < 0) {
85c9d728ddSSimon Glass 		debug("%s: Environment failed to load (err=%d)\n",
86c9d728ddSSimon Glass 		      __func__, ret);
87c9d728ddSSimon Glass 	}
88c9d728ddSSimon Glass 
89c9d728ddSSimon Glass 	return ret;
90c9d728ddSSimon Glass }
91c9d728ddSSimon Glass 
92c9d728ddSSimon Glass int env_load(void)
93c9d728ddSSimon Glass {
94c9d728ddSSimon Glass 	struct env_driver *drv = env_driver_lookup_default();
95c9d728ddSSimon Glass 	int ret = 0;
96c9d728ddSSimon Glass 
97c9d728ddSSimon Glass 	if (!drv)
98c9d728ddSSimon Glass 		return -ENODEV;
99c9d728ddSSimon Glass 	if (!drv->load)
100c9d728ddSSimon Glass 		return 0;
101c55d8b94SSimon Glass 	ret = drv->load();
102c9d728ddSSimon Glass 	if (ret) {
103c9d728ddSSimon Glass 		debug("%s: Environment failed to load (err=%d)\n", __func__,
104c9d728ddSSimon Glass 		      ret);
105c9d728ddSSimon Glass 		return ret;
106c9d728ddSSimon Glass 	}
107c9d728ddSSimon Glass 
108c9d728ddSSimon Glass 	return 0;
109c9d728ddSSimon Glass }
110c9d728ddSSimon Glass 
111c9d728ddSSimon Glass int env_save(void)
112c9d728ddSSimon Glass {
113c9d728ddSSimon Glass 	struct env_driver *drv = env_driver_lookup_default();
114c9d728ddSSimon Glass 	int ret;
115c9d728ddSSimon Glass 
116c9d728ddSSimon Glass 	if (!drv)
117c9d728ddSSimon Glass 		return -ENODEV;
118c9d728ddSSimon Glass 	if (!drv->save)
119c9d728ddSSimon Glass 		return -ENOSYS;
120c9d728ddSSimon Glass 	ret = drv->save();
121c9d728ddSSimon Glass 	if (ret) {
122c9d728ddSSimon Glass 		debug("%s: Environment failed to save (err=%d)\n", __func__,
123c9d728ddSSimon Glass 		      ret);
124c9d728ddSSimon Glass 		return ret;
125c9d728ddSSimon Glass 	}
126c9d728ddSSimon Glass 
127c9d728ddSSimon Glass 	return 0;
128c9d728ddSSimon Glass }
129c9d728ddSSimon Glass 
1306eeae424SSimon Glass int env_init(void)
131c9d728ddSSimon Glass {
132c9d728ddSSimon Glass 	struct env_driver *drv = env_driver_lookup_default();
1337938822aSSimon Glass 	int ret = -ENOENT;
134c9d728ddSSimon Glass 
135c9d728ddSSimon Glass 	if (!drv)
136c9d728ddSSimon Glass 		return -ENODEV;
1377938822aSSimon Glass 	if (drv->init)
138c9d728ddSSimon Glass 		ret = drv->init();
1397938822aSSimon Glass 	if (ret == -ENOENT) {
1407938822aSSimon Glass 		gd->env_addr = (ulong)&default_environment[0];
141eeba55cbSTom Rini 		gd->env_valid = ENV_VALID;
1427938822aSSimon Glass 
1437938822aSSimon Glass 		return 0;
1447938822aSSimon Glass 	} else if (ret) {
145c9d728ddSSimon Glass 		debug("%s: Environment failed to init (err=%d)\n", __func__,
146c9d728ddSSimon Glass 		      ret);
147c9d728ddSSimon Glass 		return ret;
148c9d728ddSSimon Glass 	}
149c9d728ddSSimon Glass 
150c9d728ddSSimon Glass 	return 0;
151c9d728ddSSimon Glass }
152