]> git.sur5r.net Git - u-boot/blob - env/env.c
53a085c43198279cc13fa77e76b73959350a732e
[u-boot] / env / env.c
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 }