2 * NVRAM variable manipulation (direct mapped flash)
4 * Copyright 2005, 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_vx.c,v 1.5.18.1 2005/09/23 06:27:05 honor Exp $
19 #include <bcmendian.h>
26 struct nvram_tuple
* BCMINIT(_nvram_realloc
)(struct nvram_tuple
*t
, const char *name
, const char *value
);
27 void BCMINIT(_nvram_free
)(struct nvram_tuple
*t
);
28 int BCMINIT(_nvram_read
)(void *buf
);
30 extern char * BCMINIT(_nvram_get
)(const char *name
);
31 extern int BCMINIT(_nvram_set
)(const char *name
, const char *value
);
32 extern int BCMINIT(_nvram_unset
)(const char *name
);
33 extern int BCMINIT(_nvram_getall
)(char *buf
, int count
);
34 extern int BCMINIT(_nvram_commit
)(struct nvram_header
*header
);
35 extern int BCMINIT(_nvram_init
)(void);
36 extern void BCMINIT(_nvram_exit
)(void);
38 static struct nvram_header
*nvram_header
= NULL
;
39 static ulong flash_base
= 0;
41 #define NVRAM_LOCK() do {} while (0)
42 #define NVRAM_UNLOCK() do {} while (0)
46 #define MB * 1024 * 1024
49 BCMINITFN(nvram_get
)(const char *name
)
54 value
= BCMINIT(_nvram_get
)(name
);
61 BCMINITFN(nvram_getall
)(char *buf
, int count
)
66 ret
= BCMINIT(_nvram_getall
)(buf
, count
);
73 BCMINITFN(nvram_set
)(const char *name
, const char *value
)
78 ret
= BCMINIT(_nvram_set
)(name
, value
);
85 BCMINITFN(nvram_unset
)(const char *name
)
90 ret
= BCMINIT(_nvram_unset
)(name
);
97 BCMINITFN(nvram_reset
)(void *sbh
)
101 uint32 watchdog
= 0, gpio
;
104 idx
= sb_coreidx(sbh
);
106 /* Check if we were soft reset */
107 if ((cc
= sb_setcore(sbh
, SB_CC
, 0))) {
108 watchdog
= R_REG(&cc
->intstatus
) & CI_WDRESET
;
109 sb_setcoreidx(sbh
, idx
);
114 value
= BCMINIT(nvram_get
)("reset_gpio");
118 gpio
= (uint32
) bcm_atoi(value
);
122 /* Setup GPIO input */
123 sb_gpioouten(sbh
, (1 << gpio
), 0);
125 /* GPIO reset is asserted low */
126 for (msec
= 0; msec
< 5000; msec
++) {
127 if (sb_gpioin(sbh
) & (1 << gpio
))
135 extern unsigned char embedded_nvram
[];
137 static struct nvram_header
*
138 BCMINITFN(find_nvram
)(bool embonly
, bool *isemb
)
140 struct nvram_header
*nvh
, tmp
;
147 if (flash_base
== SB_FLASH1
)
153 nvh
= (struct nvram_header
*)KSEG1ADDR(flash_base
+ off
- NVRAM_SPACE
);
154 if (nvh
->magic
== NVRAM_MAGIC
)
156 /* now check data integrity, checksum entire NVRAM */
157 tmp
.crc_ver_init
= htol32(nvh
->crc_ver_init
);
158 tmp
.config_refresh
= htol32(nvh
->config_refresh
);
159 tmp
.config_ncdl
= htol32(nvh
->config_ncdl
);
160 crc
= hndcrc8((char *) &tmp
+ 9, sizeof(struct nvram_header
) - 9, CRC8_INIT_VALUE
);
161 crc
= hndcrc8((char *) &nvh
[1], nvh
->len
- sizeof(struct nvram_header
), crc
);
162 /* now compare calculated checksum with one stored in NVRAM */
163 if (crc
== (nvh
->crc_ver_init
& 0xff))
164 return (nvh
); /* return if crc's match */
170 /* Now check embedded nvram */
172 nvh
= (struct nvram_header
*)KSEG1ADDR(flash_base
+ (4 * 1024));
173 if (nvh
->magic
== NVRAM_MAGIC
)
175 nvh
= (struct nvram_header
*)KSEG1ADDR(flash_base
+ 1024);
176 if (nvh
->magic
== NVRAM_MAGIC
)
179 nvh
= (struct nvram_header
*)embedded_nvram
;
180 if (nvh
->magic
== NVRAM_MAGIC
)
187 BCMINITFN(nvram_init
)(void *sbh
)
194 idx
= sb_coreidx(sbh
);
195 if (sb_setcore(sbh
, SB_CC
, 0) != NULL
) {
196 flash_base
= SB_FLASH2
;
197 sb_setcoreidx(sbh
, idx
);
199 flash_base
= SB_FLASH1
;
201 /* Temporarily initialize with embedded NVRAM */
202 nvram_header
= BCMINIT(find_nvram
)(TRUE
, &isemb
);
203 ret
= BCMINIT(_nvram_init
)();
205 /* Restore defaults from embedded NVRAM if button held down */
206 if (BCMINIT(nvram_reset
)(sbh
)) {
210 BCMINIT(_nvram_exit
)();
214 nvram_header
= BCMINIT(find_nvram
)(FALSE
, &isemb
);
215 ret
= BCMINIT(_nvram_init
)();
217 /* Restore defaults if embedded NVRAM used */
218 if (nvram_header
&& isemb
) {
226 BCMINITFN(nvram_exit
)(void)
228 BCMINIT(_nvram_exit
)();
232 BCMINITFN(_nvram_read
)(void *buf
)
238 return -19; /* -ENODEV */
240 src
= (uint32
*) nvram_header
;
241 dst
= (uint32
*) buf
;
243 for (i
= 0; i
< sizeof(struct nvram_header
); i
+= 4)
246 for (; i
< nvram_header
->len
&& i
< NVRAM_SPACE
; i
+= 4)
247 *dst
++ = ltoh32(*src
++);
253 BCMINITFN(_nvram_realloc
)(struct nvram_tuple
*t
, const char *name
, const char *value
)
255 if (!(t
= MALLOC(NULL
, sizeof(struct nvram_tuple
) + strlen(name
) + 1 + strlen(value
) + 1))) {
256 printf("_nvram_realloc: our of memory\n");
261 t
->name
= (char *) &t
[1];
262 strcpy(t
->name
, name
);
265 t
->value
= t
->name
+ strlen(name
) + 1;
266 strcpy(t
->value
, value
);
272 BCMINITFN(_nvram_free
)(struct nvram_tuple
*t
)
275 MFREE(NULL
, t
, sizeof(struct nvram_tuple
) + strlen(t
->name
) + 1 + strlen(t
->value
) + 1);
279 BCMINITFN(nvram_commit
)(void)
281 struct nvram_header
*header
;
286 if (!(header
= (struct nvram_header
*) MALLOC(NULL
, NVRAM_SPACE
))) {
287 printf("nvram_commit: out of memory\n");
288 return -12; /* -ENOMEM */
293 /* Regenerate NVRAM */
294 ret
= BCMINIT(_nvram_commit
)(header
);
298 src
= (uint32
*) &header
[1];
301 for (i
= sizeof(struct nvram_header
); i
< header
->len
&& i
< NVRAM_SPACE
; i
+= 4)
302 *dst
++ = htol32(*src
++);
305 if ((ret
= cfe_open("flash0.nvram")) >= 0) {
306 cfe_writeblk(ret
, 0, (unsigned char *) header
, header
->len
);
310 if (sysFlashInit(NULL
) == 0)
311 nvWrite((unsigned short *) header
, NVRAM_SPACE
);
316 MFREE(NULL
, header
, NVRAM_SPACE
);