2 * NVRAM variable manipulation (direct mapped flash)
4 * Copyright 2007, 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.
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 *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)
47 #define MB * 1024 * 1024
50 nvram_get(const char *name
)
55 value
= _nvram_get(name
);
62 nvram_getall(char *buf
, int count
)
67 ret
= _nvram_getall(buf
, count
);
74 BCMINITFN(nvram_set
)(const char *name
, const char *value
)
79 ret
= _nvram_set(name
, value
);
86 BCMINITFN(nvram_unset
)(const char *name
)
91 ret
= _nvram_unset(name
);
98 BCMINITFN(nvram_resetgpio_init
)(void *sb
)
106 value
= nvram_get("reset_gpio");
110 gpio
= (int) bcm_atoi(value
);
114 /* Setup GPIO input */
115 sb_gpioouten(sbh
, ((uint32
) 1 << gpio
), 0, GPIO_DRV_PRIORITY
);
121 BCMINITFN(nvram_reset
)(void *sb
)
125 sb_t
* sbh
= (sb_t
*)sb
;
127 if ((gpio
= nvram_resetgpio_init((void *)sbh
)) < 0)
130 /* GPIO reset is asserted low */
131 for (msec
= 0; msec
< 5000; msec
++) {
132 if (sb_gpioin(sbh
) & ((uint32
) 1 << gpio
))
137 nvram_do_reset
= 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
;
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) */{
164 /* Now check embedded nvram */
166 nvh
= (struct nvram_header
*)KSEG1ADDR(SB_FLASH2
+ (4 * 1024));
167 if (nvh
->magic
== NVRAM_MAGIC
)
169 nvh
= (struct nvram_header
*)KSEG1ADDR(SB_FLASH2
+ 1024);
170 if (nvh
->magic
== NVRAM_MAGIC
)
173 nvh
= (struct nvram_header
*)embedded_nvram
;
174 if (nvh
->magic
== NVRAM_MAGIC
)
177 printf("find_nvram: no nvram found\n");
182 BCMINITFN(nvram_init
)(void *sb
)
187 static int nvram_status
= -1;
189 /* Check for previous 'restore defaults' condition */
190 if (nvram_status
== 1)
193 /* Check whether nvram already initilized */
194 if (nvram_status
== 0 && !nvram_do_reset
)
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
);
213 nvram_header
= find_nvram(FALSE
, &isemb
);
214 ret
= _nvram_init(sb
);
216 /* Restore defaults if embedded NVRAM used */
217 if (nvram_header
&& isemb
) {
226 BCMINITFN(nvram_append
)(void *sb
, char *vars
, uint varsz
)
232 BCMINITFN(nvram_exit
)(void *sb
)
242 BCMINITFN(_nvram_read
)(void *buf
)
248 return -19; /* -ENODEV */
250 src
= (uint32
*) nvram_header
;
251 dst
= (uint32
*) buf
;
253 for (i
= 0; i
< sizeof(struct nvram_header
); i
+= 4)
256 for (; i
< nvram_header
->len
&& i
< NVRAM_SPACE
; i
+= 4)
257 *dst
++ = ltoh32(*src
++);
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");
272 t
->name
= (char *) &t
[1];
273 strcpy(t
->name
, name
);
276 t
->value
= t
->name
+ strlen(name
) + 1;
277 strcpy(t
->value
, value
);
283 BCMINITFN(_nvram_free
)(struct nvram_tuple
*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
;
298 if (!(header
= (struct nvram_header
*) MALLOC(NULL
, NVRAM_SPACE
))) {
299 printf("nvram_commit: out of memory\n");
300 return -12; /* -ENOMEM */
305 /* Regenerate NVRAM */
306 ret
= _nvram_commit(header
);
310 src
= (uint32
*) &header
[1];
313 for (i
= sizeof(struct nvram_header
); i
< header
->len
&& i
< NVRAM_SPACE
; i
+= 4)
314 *dst
++ = htol32(*src
++);
317 if ((ret
= cfe_open("flash0.nvram")) >= 0) {
318 cfe_writeblk(ret
, 0, (unsigned char *) header
, header
->len
);
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_ */
340 MFREE(NULL
, header
, NVRAM_SPACE
);