]> git.sur5r.net Git - u-boot/blob - env/env.c
Merge git://www.denx.de/git/u-boot-imx
[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_EEPROM)
32                 return ENVL_EEPROM;
33         else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT)
34                 return ENVL_FAT;
35         else if IS_ENABLED(CONFIG_ENV_IS_IN_FLASH)
36                 return ENVL_FLASH;
37         else if IS_ENABLED(CONFIG_ENV_IS_IN_MMC)
38                 return ENVL_MMC;
39         else if IS_ENABLED(CONFIG_ENV_IS_IN_NAND)
40                 return ENVL_NAND;
41         else if IS_ENABLED(CONFIG_ENV_IS_IN_NVRAM)
42                 return ENVL_NVRAM;
43         else if IS_ENABLED(CONFIG_ENV_IS_IN_REMOTE)
44                 return ENVL_REMOTE;
45         else if IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH)
46                 return ENVL_SPI_FLASH;
47         else if IS_ENABLED(CONFIG_ENV_IS_IN_UBI)
48                 return ENVL_UBI;
49         else if IS_ENABLED(CONFIG_ENV_IS_NOWHERE)
50                 return ENVL_NOWHERE;
51         else
52                 return ENVL_UNKNOWN;
53 }
54
55 struct env_driver *env_driver_lookup_default(void)
56 {
57         enum env_location loc = env_get_default_location();
58         struct env_driver *drv;
59
60         drv = env_driver_lookup(loc);
61         if (!drv) {
62                 debug("%s: No environment driver for location %d\n", __func__,
63                       loc);
64                 return NULL;
65         }
66
67         return drv;
68 }
69
70 int env_get_char(int index)
71 {
72         struct env_driver *drv = env_driver_lookup_default();
73         int ret;
74
75         if (gd->env_valid == ENV_INVALID)
76                 return default_environment[index];
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         ret = drv->load();
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(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 = ENV_VALID;
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 }