]> Git Repo - J-u-boot.git/blob - env/eeprom.c
Merge patch series "clk: mediatek: mt7622: clk migration for OF_UPSTREAM"
[J-u-boot.git] / env / eeprom.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2000-2010
4  * Wolfgang Denk, DENX Software Engineering, [email protected].
5  *
6  * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
7  * Andreas Heppel <[email protected]>
8  */
9
10 #include <command.h>
11 #include <eeprom.h>
12 #include <env.h>
13 #include <env_internal.h>
14 #include <asm/global_data.h>
15 #include <linux/stddef.h>
16 #include <u-boot/crc.h>
17 #include <search.h>
18 #include <errno.h>
19 #include <linux/compiler.h>     /* for BUG_ON */
20
21 DECLARE_GLOBAL_DATA_PTR;
22
23 static int env_eeprom_load(void)
24 {
25         char buf_env[CONFIG_ENV_SIZE];
26         unsigned int off = CONFIG_ENV_OFFSET;
27
28 #ifdef CONFIG_ENV_OFFSET_REDUND
29         ulong len, crc[2], crc_tmp;
30         unsigned int off_env[2];
31         uchar rdbuf[64], flags[2];
32         int i, crc_ok[2] = {0, 0};
33
34         eeprom_init(-1);        /* prepare for EEPROM read/write */
35
36         off_env[0] = CONFIG_ENV_OFFSET;
37         off_env[1] = CONFIG_ENV_OFFSET_REDUND;
38
39         for (i = 0; i < 2; i++) {
40                 /* read CRC */
41                 eeprom_read(CONFIG_SYS_I2C_EEPROM_ADDR,
42                                 off_env[i] + offsetof(env_t, crc),
43                                 (uchar *)&crc[i], sizeof(ulong));
44                 /* read FLAGS */
45                 eeprom_read(CONFIG_SYS_I2C_EEPROM_ADDR,
46                                 off_env[i] + offsetof(env_t, flags),
47                                 (uchar *)&flags[i], sizeof(uchar));
48
49                 crc_tmp = 0;
50                 len = ENV_SIZE;
51                 off = off_env[i] + offsetof(env_t, data);
52                 while (len > 0) {
53                         int n = (len > sizeof(rdbuf)) ? sizeof(rdbuf) : len;
54
55                         eeprom_read(CONFIG_SYS_I2C_EEPROM_ADDR, off,
56                                         rdbuf, n);
57
58                         crc_tmp = crc32(crc_tmp, rdbuf, n);
59                         len -= n;
60                         off += n;
61                 }
62
63                 if (crc_tmp == crc[i])
64                         crc_ok[i] = 1;
65         }
66
67         if (!crc_ok[0] && !crc_ok[1]) {
68                 gd->env_addr    = 0;
69                 gd->env_valid = ENV_INVALID;
70         } else if (crc_ok[0] && !crc_ok[1]) {
71                 gd->env_valid = ENV_VALID;
72         } else if (!crc_ok[0] && crc_ok[1]) {
73                 gd->env_valid = ENV_REDUND;
74         } else {
75                 /* both ok - check serial */
76                 if (flags[0] == ENV_REDUND_ACTIVE &&
77                     flags[1] == ENV_REDUND_OBSOLETE)
78                         gd->env_valid = ENV_VALID;
79                 else if (flags[0] == ENV_REDUND_OBSOLETE &&
80                          flags[1] == ENV_REDUND_ACTIVE)
81                         gd->env_valid = ENV_REDUND;
82                 else if (flags[0] == 0xFF && flags[1] == 0)
83                         gd->env_valid = ENV_REDUND;
84                 else if (flags[1] == 0xFF && flags[0] == 0)
85                         gd->env_valid = ENV_VALID;
86                 else /* flags are equal - almost impossible */
87                         gd->env_valid = ENV_VALID;
88         }
89
90 #else /* CONFIG_ENV_OFFSET_REDUND */
91         ulong crc, len, new;
92         uchar rdbuf[64];
93
94         eeprom_init(-1);        /* prepare for EEPROM read/write */
95
96         /* read old CRC */
97         eeprom_read(CONFIG_SYS_I2C_EEPROM_ADDR,
98                         CONFIG_ENV_OFFSET + offsetof(env_t, crc),
99                         (uchar *)&crc, sizeof(ulong));
100
101         new = 0;
102         len = ENV_SIZE;
103         off = offsetof(env_t, data);
104         while (len > 0) {
105                 int n = (len > sizeof(rdbuf)) ? sizeof(rdbuf) : len;
106
107                 eeprom_read(CONFIG_SYS_I2C_EEPROM_ADDR,
108                                 CONFIG_ENV_OFFSET + off, rdbuf, n);
109                 new = crc32(new, rdbuf, n);
110                 len -= n;
111                 off += n;
112         }
113
114         if (crc == new) {
115                 gd->env_valid = ENV_VALID;
116         } else {
117                 gd->env_valid = ENV_INVALID;
118         }
119 #endif /* CONFIG_ENV_OFFSET_REDUND */
120
121         off = CONFIG_ENV_OFFSET;
122 #ifdef CONFIG_ENV_OFFSET_REDUND
123         if (gd->env_valid == ENV_REDUND)
124                 off = CONFIG_ENV_OFFSET_REDUND;
125 #endif
126
127         eeprom_read(CONFIG_SYS_I2C_EEPROM_ADDR,
128                 off, (uchar *)buf_env, CONFIG_ENV_SIZE);
129
130         return env_import(buf_env, 1, H_EXTERNAL);
131 }
132
133 static int env_eeprom_save(void)
134 {
135         env_t   env_new;
136         int     rc;
137         unsigned int off        = CONFIG_ENV_OFFSET;
138 #ifdef CONFIG_ENV_OFFSET_REDUND
139         unsigned int off_red    = CONFIG_ENV_OFFSET_REDUND;
140         char flag_obsolete      = ENV_REDUND_OBSOLETE;
141 #endif
142
143         rc = env_export(&env_new);
144         if (rc)
145                 return rc;
146
147 #ifdef CONFIG_ENV_OFFSET_REDUND
148         if (gd->env_valid == ENV_VALID) {
149                 off     = CONFIG_ENV_OFFSET_REDUND;
150                 off_red = CONFIG_ENV_OFFSET;
151         }
152
153         env_new.flags = ENV_REDUND_ACTIVE;
154 #endif
155
156         rc = eeprom_write(CONFIG_SYS_I2C_EEPROM_ADDR,
157                               off, (uchar *)&env_new, CONFIG_ENV_SIZE);
158
159 #ifdef CONFIG_ENV_OFFSET_REDUND
160         if (rc == 0) {
161                 eeprom_write(CONFIG_SYS_I2C_EEPROM_ADDR,
162                                  off_red + offsetof(env_t, flags),
163                                  (uchar *)&flag_obsolete, 1);
164
165                 if (gd->env_valid == ENV_VALID)
166                         gd->env_valid = ENV_REDUND;
167                 else
168                         gd->env_valid = ENV_VALID;
169         }
170 #endif
171         return rc;
172 }
173
174 U_BOOT_ENV_LOCATION(eeprom) = {
175         .location       = ENVL_EEPROM,
176         ENV_NAME("EEPROM")
177         .load           = env_eeprom_load,
178         .save           = env_save_ptr(env_eeprom_save),
179 };
This page took 0.035524 seconds and 4 git commands to generate.