blob: 6195d3b2f308f4149b2c1d14197cff4dd5b81bc6 [file] [log] [blame]
Simon Glass15e5a1a2017-08-03 12:22:00 -06001/*
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
11DECLARE_GLOBAL_DATA_PTR;
12
13static 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
29static enum env_location env_get_default_location(void)
30{
Tuomas Tynkkynenbfef2972017-10-10 21:59:40 +030031 if IS_ENABLED(CONFIG_ENV_IS_IN_EEPROM)
Simon Glass15e5a1a2017-08-03 12:22:00 -060032 return ENVL_EEPROM;
33 else if IS_ENABLED(CONFIG_ENV_IS_IN_FAT)
34 return ENVL_FAT;
Jorge Ramirez-Ortiz4a4c26d2018-01-10 11:33:48 +010035 else if IS_ENABLED(CONFIG_ENV_IS_IN_EXT4)
36 return ENVL_EXT4;
Simon Glass15e5a1a2017-08-03 12:22:00 -060037 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
Maxime Ripard3c0b2e52018-01-23 21:16:50 +010057static struct env_driver *env_driver_lookup_default(void)
Simon Glass15e5a1a2017-08-03 12:22:00 -060058{
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
Simon Glass10b0d7b2017-08-03 12:22:06 -060072int env_get_char(int index)
Simon Glass15e5a1a2017-08-03 12:22:00 -060073{
74 struct env_driver *drv = env_driver_lookup_default();
75 int ret;
76
Simon Glass1f39d0b2017-08-20 04:45:15 -060077 if (gd->env_valid == ENV_INVALID)
Simon Glass10b0d7b2017-08-03 12:22:06 -060078 return default_environment[index];
Simon Glass15e5a1a2017-08-03 12:22:00 -060079 if (!drv)
80 return -ENODEV;
81 if (!drv->get_char)
82 return *(uchar *)(gd->env_addr + index);
83 ret = drv->get_char(index);
84 if (ret < 0) {
85 debug("%s: Environment failed to load (err=%d)\n",
86 __func__, ret);
87 }
88
89 return ret;
90}
91
92int env_load(void)
93{
94 struct env_driver *drv = env_driver_lookup_default();
95 int ret = 0;
96
97 if (!drv)
98 return -ENODEV;
99 if (!drv->load)
100 return 0;
Simon Glass3e238a22017-08-20 04:45:14 -0600101 ret = drv->load();
Simon Glass15e5a1a2017-08-03 12:22:00 -0600102 if (ret) {
103 debug("%s: Environment failed to load (err=%d)\n", __func__,
104 ret);
105 return ret;
106 }
107
108 return 0;
109}
110
111int env_save(void)
112{
113 struct env_driver *drv = env_driver_lookup_default();
114 int ret;
115
116 if (!drv)
117 return -ENODEV;
118 if (!drv->save)
119 return -ENOSYS;
Maxime Ripard3c0b2e52018-01-23 21:16:50 +0100120
121 printf("Saving Environment to %s...\n", drv->name);
Simon Glass15e5a1a2017-08-03 12:22:00 -0600122 ret = drv->save();
123 if (ret) {
124 debug("%s: Environment failed to save (err=%d)\n", __func__,
125 ret);
126 return ret;
127 }
128
129 return 0;
130}
131
Simon Glass36d85812017-08-03 12:22:05 -0600132int env_init(void)
Simon Glass15e5a1a2017-08-03 12:22:00 -0600133{
134 struct env_driver *drv = env_driver_lookup_default();
Simon Glassd40d8042017-08-03 12:22:02 -0600135 int ret = -ENOENT;
Simon Glass15e5a1a2017-08-03 12:22:00 -0600136
137 if (!drv)
138 return -ENODEV;
Simon Glassd40d8042017-08-03 12:22:02 -0600139 if (drv->init)
140 ret = drv->init();
141 if (ret == -ENOENT) {
142 gd->env_addr = (ulong)&default_environment[0];
Tom Rini8a7c44b2017-08-19 22:27:57 -0400143 gd->env_valid = ENV_VALID;
Simon Glassd40d8042017-08-03 12:22:02 -0600144
145 return 0;
146 } else if (ret) {
Simon Glass15e5a1a2017-08-03 12:22:00 -0600147 debug("%s: Environment failed to init (err=%d)\n", __func__,
148 ret);
149 return ret;
150 }
151
152 return 0;
153}