Updates to Tomato RAF including NGINX && PHP
[tomato.git] / release / src / shared / nvram / nvram_rw.c
blobbfdcd52ead46f00e62ef5f7cb155ba2350da888a
1 /*
2 * NVRAM variable manipulation (direct mapped flash)
4 * Copyright 2007, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
12 * $Id$
15 #include <typedefs.h>
16 #include <bcmdefs.h>
17 #include <osl.h>
18 #include <bcmutils.h>
19 #include <sbutils.h>
20 #include <mipsinc.h>
21 #include <bcmnvram.h>
22 #include <bcmendian.h>
23 #include <flashutl.h>
24 #include <sbconfig.h>
25 #include <sbchipc.h>
27 struct nvram_tuple * _nvram_realloc(struct nvram_tuple *t, const char *name, const char *value);
28 void _nvram_free(struct nvram_tuple *t);
29 int _nvram_read(void *buf);
31 extern char *_nvram_get(const char *name);
32 extern int _nvram_set(const char *name, const char *value);
33 extern int _nvram_unset(const char *name);
34 extern int _nvram_getall(char *buf, int count);
35 extern int _nvram_commit(struct nvram_header *header);
36 extern int _nvram_init(void *sb);
37 extern void _nvram_exit(void);
39 static struct nvram_header *nvram_header = NULL;
40 static bool nvram_do_reset = FALSE;
42 #define NVRAM_LOCK() do {} while (0)
43 #define NVRAM_UNLOCK() do {} while (0)
45 /* Convenience */
46 #define KB * 1024
47 #define MB * 1024 * 1024
49 char *
50 nvram_get(const char *name)
52 char *value;
54 NVRAM_LOCK();
55 value = _nvram_get(name);
56 NVRAM_UNLOCK();
58 return value;
61 int
62 nvram_getall(char *buf, int count)
64 int ret;
66 NVRAM_LOCK();
67 ret = _nvram_getall(buf, count);
68 NVRAM_UNLOCK();
70 return ret;
73 int
74 BCMINITFN(nvram_set)(const char *name, const char *value)
76 int ret;
78 NVRAM_LOCK();
79 ret = _nvram_set(name, value);
80 NVRAM_UNLOCK();
82 return ret;
85 int
86 BCMINITFN(nvram_unset)(const char *name)
88 int ret;
90 NVRAM_LOCK();
91 ret = _nvram_unset(name);
92 NVRAM_UNLOCK();
94 return ret;
97 int
98 BCMINITFN(nvram_resetgpio_init)(void *sb)
100 char *value;
101 int gpio;
102 sb_t *sbh;
104 sbh = (sb_t *)sb;
106 value = nvram_get("reset_gpio");
107 if (!value)
108 return -1;
110 gpio = (int) bcm_atoi(value);
111 if (gpio > 7)
112 return -1;
114 /* Setup GPIO input */
115 sb_gpioouten(sbh, ((uint32) 1 << gpio), 0, GPIO_DRV_PRIORITY);
117 return gpio;
120 bool
121 BCMINITFN(nvram_reset)(void *sb)
123 int gpio;
124 uint msec;
125 sb_t * sbh = (sb_t *)sb;
127 if ((gpio = nvram_resetgpio_init((void *)sbh)) < 0)
128 return FALSE;
130 /* GPIO reset is asserted low */
131 for (msec = 0; msec < 5000; msec++) {
132 if (sb_gpioin(sbh) & ((uint32) 1 << gpio))
133 return FALSE;
134 OSL_DELAY(1000);
137 nvram_do_reset = TRUE;
138 return TRUE;
141 extern unsigned char embedded_nvram[];
143 static struct nvram_header *
144 BCMINITFN(find_nvram)(bool embonly, bool *isemb)
146 struct nvram_header *nvh;
147 uint32 off, lim;
150 if (!embonly) {
151 *isemb = FALSE;
152 lim = SB_FLASH2_SZ;
153 off = FLASH_MIN;
154 while (off <= lim) {
155 nvh = (struct nvram_header *)KSEG1ADDR(SB_FLASH2 + off - NVRAM_SPACE);
156 if (nvh->magic == NVRAM_MAGIC)
157 /* if (nvram_calc_crc(nvh) == (uint8) nvh->crc_ver_init) */{
158 return (nvh);
160 off <<= 1;
164 /* Now check embedded nvram */
165 *isemb = TRUE;
166 nvh = (struct nvram_header *)KSEG1ADDR(SB_FLASH2 + (4 * 1024));
167 if (nvh->magic == NVRAM_MAGIC)
168 return (nvh);
169 nvh = (struct nvram_header *)KSEG1ADDR(SB_FLASH2 + 1024);
170 if (nvh->magic == NVRAM_MAGIC)
171 return (nvh);
172 #ifdef _CFE_
173 nvh = (struct nvram_header *)embedded_nvram;
174 if (nvh->magic == NVRAM_MAGIC)
175 return (nvh);
176 #endif
177 printf("find_nvram: no nvram found\n");
178 return (NULL);
182 BCMINITFN(nvram_init)(void *sb)
184 bool isemb;
185 int ret;
186 sb_t *sbh;
187 static int nvram_status = -1;
189 /* Check for previous 'restore defaults' condition */
190 if (nvram_status == 1)
191 return 1;
193 /* Check whether nvram already initilized */
194 if (nvram_status == 0 && !nvram_do_reset)
195 return 0;
197 sbh = (sb_t *)sb;
199 /* Restore defaults from embedded NVRAM if button held down */
200 if (nvram_do_reset) {
201 /* Initialize with embedded NVRAM */
202 nvram_header = find_nvram(TRUE, &isemb);
203 ret = _nvram_init(sb);
204 if (ret == 0) {
205 nvram_status = 1;
206 return 1;
208 nvram_status = -1;
209 _nvram_exit();
212 /* Find NVRAM */
213 nvram_header = find_nvram(FALSE, &isemb);
214 ret = _nvram_init(sb);
215 if (ret == 0) {
216 /* Restore defaults if embedded NVRAM used */
217 if (nvram_header && isemb) {
218 ret = 1;
221 nvram_status = ret;
222 return ret;
226 BCMINITFN(nvram_append)(void *sb, char *vars, uint varsz)
228 return 0;
231 void
232 BCMINITFN(nvram_exit)(void *sb)
234 sb_t *sbh;
236 sbh = (sb_t *)sb;
238 _nvram_exit();
242 BCMINITFN(_nvram_read)(void *buf)
244 uint32 *src, *dst;
245 uint i;
247 if (!nvram_header)
248 return -19; /* -ENODEV */
250 src = (uint32 *) nvram_header;
251 dst = (uint32 *) buf;
253 for (i = 0; i < sizeof(struct nvram_header); i += 4)
254 *dst++ = *src++;
256 for (; i < nvram_header->len && i < NVRAM_SPACE; i += 4)
257 *dst++ = ltoh32(*src++);
259 return 0;
262 struct nvram_tuple *
263 BCMINITFN(_nvram_realloc)(struct nvram_tuple *t, const char *name, const char *value)
265 if (!(t = MALLOC(NULL, sizeof(struct nvram_tuple) + strlen(name) + 1 +
266 strlen(value) + 1))) {
267 printf("_nvram_realloc: our of memory\n");
268 return NULL;
271 /* Copy name */
272 t->name = (char *) &t[1];
273 strcpy(t->name, name);
275 /* Copy value */
276 t->value = t->name + strlen(name) + 1;
277 strcpy(t->value, value);
279 return t;
282 void
283 BCMINITFN(_nvram_free)(struct nvram_tuple *t)
285 if (t)
286 MFREE(NULL, t, sizeof(struct nvram_tuple) + strlen(t->name) + 1 +
287 strlen(t->value) + 1);
291 BCMINITFN(nvram_commit)(void)
293 struct nvram_header *header;
294 int ret;
295 uint32 *src, *dst;
296 uint i;
298 if (!(header = (struct nvram_header *) MALLOC(NULL, NVRAM_SPACE))) {
299 printf("nvram_commit: out of memory\n");
300 return -12; /* -ENOMEM */
303 NVRAM_LOCK();
305 /* Regenerate NVRAM */
306 ret = _nvram_commit(header);
307 if (ret)
308 goto done;
310 src = (uint32 *) &header[1];
311 dst = src;
313 for (i = sizeof(struct nvram_header); i < header->len && i < NVRAM_SPACE; i += 4)
314 *dst++ = htol32(*src++);
316 #ifdef _CFE_
317 if ((ret = cfe_open("flash0.nvram")) >= 0) {
318 cfe_writeblk(ret, 0, (unsigned char *) header, header->len);
319 cfe_close(ret);
321 #else
322 if (sysFlashInit(NULL) == 0) {
323 /* set/write invalid MAGIC # (in case writing image fails/is interrupted)
324 write the NVRAM image to flash(with invalid magic)
325 set/write valid MAGIC #
327 header->magic = NVRAM_CLEAR_MAGIC;
328 nvWriteChars((unsigned char *)&header->magic, sizeof(header->magic));
330 header->magic = NVRAM_INVALID_MAGIC;
331 nvWrite((unsigned short *) header, NVRAM_SPACE);
333 header->magic = NVRAM_MAGIC;
334 nvWriteChars((unsigned char *)&header->magic, sizeof(header->magic));
336 #endif /* ifdef _CFE_ */
338 done:
339 NVRAM_UNLOCK();
340 MFREE(NULL, header, NVRAM_SPACE);
341 return ret;