2 * NVRAM variable manipulation (direct mapped flash)
4 * Copyright (C) 2009, Broadcom Corporation
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: nvram_rw.c,v 1.51 2010/01/05 19:11:25 Exp $
22 #include <bcmendian.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 *si
);
37 extern void _nvram_exit(void);
40 extern int kernel_initial
;
43 static struct nvram_header
*nvram_header
= NULL
;
44 static int nvram_do_reset
= FALSE
;
46 #define NVRAM_LOCK() do {} while (0)
47 #define NVRAM_UNLOCK() do {} while (0)
51 #define MB * 1024 * 1024
54 nvram_get(const char *name
)
64 value
= _nvram_get(name
);
71 nvram_getall(char *buf
, int count
)
76 ret
= _nvram_getall(buf
, count
);
83 BCMINITFN(nvram_set
)(const char *name
, const char *value
)
88 ret
= _nvram_set(name
, value
);
95 BCMINITFN(nvram_unset
)(const char *name
)
100 ret
= _nvram_unset(name
);
107 BCMINITFN(nvram_resetgpio_init
)(void *si
)
115 value
= nvram_get("reset_gpio");
119 gpio
= (int) bcm_atoi(value
);
123 /* Setup GPIO input */
124 si_gpioouten(sih
, ((uint32
) 1 << gpio
), 0, GPIO_DRV_PRIORITY
);
130 BCMINITFN(nvram_reset
)(void *si
)
134 si_t
* sih
= (si_t
*)si
;
136 if ((gpio
= nvram_resetgpio_init((void *)sih
)) < 0)
139 /* GPIO reset is asserted low */
140 for (msec
= 0; msec
< 5000; msec
++) {
141 if (si_gpioin(sih
) & ((uint32
) 1 << gpio
))
146 nvram_do_reset
= TRUE
;
150 extern unsigned char embedded_nvram
[];
152 static struct nvram_header
*
153 BCMINITFN(find_nvram
)(bool embonly
, bool *isemb
)
155 struct nvram_header
*nvh
;
164 nvh
= (struct nvram_header
*)KSEG1ADDR(SI_FLASH2
+ off
- NVRAM_SPACE
);
165 if (nvh
->magic
== NVRAM_MAGIC
)
166 /* if (nvram_calc_crc(nvh) == (uint8) nvh->crc_ver_init) */{
172 printf("find_nvram: nvram not found, trying embedded nvram next\n");
176 /* Now check embedded nvram */
178 nvh
= (struct nvram_header
*)KSEG1ADDR(SI_FLASH2
+ (4 * 1024));
179 if (nvh
->magic
== NVRAM_MAGIC
)
181 nvh
= (struct nvram_header
*)KSEG1ADDR(SI_FLASH2
+ 1024);
182 if (nvh
->magic
== NVRAM_MAGIC
)
185 nvh
= (struct nvram_header
*)embedded_nvram
;
186 if (nvh
->magic
== NVRAM_MAGIC
)
189 printf("find_nvram: no nvram found\n");
194 BCMATTACHFN(nvram_init
)(void *si
)
199 static int nvram_status
= -1;
206 /* Check for previous 'restore defaults' condition */
207 if (nvram_status
== 1)
210 /* Check whether nvram already initilized */
211 if (nvram_status
== 0 && !nvram_do_reset
)
216 /* Restore defaults from embedded NVRAM if button held down */
217 if (nvram_do_reset
) {
218 /* Initialize with embedded NVRAM */
219 nvram_header
= find_nvram(TRUE
, &isemb
);
220 ret
= _nvram_init(si
);
230 nvram_header
= find_nvram(FALSE
, &isemb
);
231 ret
= _nvram_init(si
);
233 /* Restore defaults if embedded NVRAM used */
234 if (nvram_header
&& isemb
) {
243 BCMINITFN(nvram_append
)(void *si
, char *vars
, uint varsz
)
249 BCMINITFN(nvram_exit
)(void *si
)
259 BCMINITFN(_nvram_read
)(void *buf
)
265 return -19; /* -ENODEV */
267 src
= (uint32
*) nvram_header
;
268 dst
= (uint32
*) buf
;
270 for (i
= 0; i
< sizeof(struct nvram_header
); i
+= 4)
273 for (; i
< nvram_header
->len
&& i
< NVRAM_SPACE
; i
+= 4)
274 *dst
++ = ltoh32(*src
++);
280 BCMINITFN(_nvram_realloc
)(struct nvram_tuple
*t
, const char *name
, const char *value
)
282 if (!(t
= MALLOC(NULL
, sizeof(struct nvram_tuple
) + strlen(name
) + 1 +
283 strlen(value
) + 1))) {
284 printf("_nvram_realloc: our of memory\n");
289 t
->name
= (char *) &t
[1];
290 strcpy(t
->name
, name
);
293 t
->value
= t
->name
+ strlen(name
) + 1;
294 strcpy(t
->value
, value
);
300 BCMINITFN(_nvram_free
)(struct nvram_tuple
*t
)
303 MFREE(NULL
, t
, sizeof(struct nvram_tuple
) + strlen(t
->name
) + 1 +
304 strlen(t
->value
) + 1);
308 BCMINITFN(nvram_commit
)(void)
310 struct nvram_header
*header
;
315 if (!(header
= (struct nvram_header
*) MALLOC(NULL
, NVRAM_SPACE
))) {
316 printf("nvram_commit: out of memory\n");
317 return -12; /* -ENOMEM */
322 /* Regenerate NVRAM */
323 ret
= _nvram_commit(header
);
327 src
= (uint32
*) &header
[1];
330 for (i
= sizeof(struct nvram_header
); i
< header
->len
&& i
< NVRAM_SPACE
; i
+= 4)
331 *dst
++ = htol32(*src
++);
334 if ((ret
= cfe_open("flash0.nvram")) >= 0) {
335 cfe_writeblk(ret
, 0, (unsigned char *) header
, header
->len
);
339 if (sysFlashInit(NULL
) == 0) {
340 /* set/write invalid MAGIC # (in case writing image fails/is interrupted)
341 * write the NVRAM image to flash(with invalid magic)
342 * set/write valid MAGIC #
344 header
->magic
= NVRAM_CLEAR_MAGIC
;
345 nvWriteChars((unsigned char *)&header
->magic
, sizeof(header
->magic
));
347 header
->magic
= NVRAM_INVALID_MAGIC
;
348 nvWrite((unsigned short *) header
, NVRAM_SPACE
);
350 header
->magic
= NVRAM_MAGIC
;
351 nvWriteChars((unsigned char *)&header
->magic
, sizeof(header
->magic
));
353 #endif /* ifdef _CFE_ */
357 MFREE(NULL
, header
, NVRAM_SPACE
);