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