2 * NVRAM variable manipulation (common)
4 * Copyright 2004, 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.
17 #include <bcmendian.h>
22 extern struct nvram_tuple
* _nvram_realloc(struct nvram_tuple
*t
, const char *name
, const char *value
);
23 extern void _nvram_free(struct nvram_tuple
*t
);
24 extern int _nvram_read(void *buf
);
26 char * _nvram_get(const char *name
);
27 int _nvram_set(const char *name
, const char *value
);
28 int _nvram_unset(const char *name
);
29 int _nvram_getall(char *buf
, int count
);
30 int _nvram_commit(struct nvram_header
*header
);
31 int _nvram_init(void);
32 void _nvram_exit(void);
34 static struct nvram_tuple
* nvram_hash
[257];
35 static struct nvram_tuple
* nvram_dead
;
37 /* Free all tuples. Should be locked. */
42 struct nvram_tuple
*t
, *next
;
45 for (i
= 0; i
< ARRAYSIZE(nvram_hash
); i
++) {
46 for (t
= nvram_hash
[i
]; t
; t
= next
) {
54 for (t
= nvram_dead
; t
; t
= next
) {
60 /* Indicate to per-port code that all tuples have been freed */
71 hash
= 31 * hash
+ *s
++;
76 /* (Re)initialize the hash table. Should be locked. */
78 nvram_rehash(struct nvram_header
*header
)
80 char buf
[] = "0xXXXXXXXX", *name
, *value
, *end
, *eq
;
82 /* (Re)initialize hash table */
85 /* Parse and set "name=value\0 ... \0\0" */
86 name
= (char *) &header
[1];
87 end
= (char *) header
+ NVRAM_SPACE
- 2;
88 end
[0] = end
[1] = '\0';
89 for (; *name
; name
= value
+ strlen(value
) + 1) {
90 if (!(eq
= strchr(name
, '=')))
94 _nvram_set(name
, value
);
98 /* Set special SDRAM parameters */
99 if (!_nvram_get("sdram_init")) {
100 sprintf(buf
, "0x%04X", (uint16
)(header
->crc_ver_init
>> 16));
101 _nvram_set("sdram_init", buf
);
103 if (!_nvram_get("sdram_config")) {
104 sprintf(buf
, "0x%04X", (uint16
)(header
->config_refresh
& 0xffff));
105 _nvram_set("sdram_config", buf
);
107 if (!_nvram_get("sdram_refresh")) {
108 sprintf(buf
, "0x%04X", (uint16
)((header
->config_refresh
>> 16) & 0xffff));
109 _nvram_set("sdram_refresh", buf
);
111 if (!_nvram_get("sdram_ncdl")) {
112 sprintf(buf
, "0x%08X", header
->config_ncdl
);
113 _nvram_set("sdram_ncdl", buf
);
119 /* Get the value of an NVRAM variable. Should be locked. */
121 _nvram_get(const char *name
)
124 struct nvram_tuple
*t
;
131 i
= hash(name
) % ARRAYSIZE(nvram_hash
);
133 /* Find the associated tuple in the hash table */
134 for (t
= nvram_hash
[i
]; t
&& strcmp(t
->name
, name
); t
= t
->next
);
136 value
= t
? t
->value
: NULL
;
141 /* Get the value of an NVRAM variable. Should be locked. */
143 _nvram_set(const char *name
, const char *value
)
146 struct nvram_tuple
*t
, *u
, **prev
;
149 i
= hash(name
) % ARRAYSIZE(nvram_hash
);
151 /* Find the associated tuple in the hash table */
152 for (prev
= &nvram_hash
[i
], t
= *prev
; t
&& strcmp(t
->name
, name
); prev
= &t
->next
, t
= *prev
);
154 /* (Re)allocate tuple */
155 if (!(u
= _nvram_realloc(t
, name
, value
)))
156 return -12; /* -ENOMEM */
158 /* Value reallocated */
162 /* Move old tuple to the dead table */
165 t
->next
= nvram_dead
;
169 /* Add new tuple to the hash table */
170 u
->next
= nvram_hash
[i
];
176 /* Unset the value of an NVRAM variable. Should be locked. */
178 _nvram_unset(const char *name
)
181 struct nvram_tuple
*t
, **prev
;
187 i
= hash(name
) % ARRAYSIZE(nvram_hash
);
189 /* Find the associated tuple in the hash table */
190 for (prev
= &nvram_hash
[i
], t
= *prev
; t
&& strcmp(t
->name
, name
); prev
= &t
->next
, t
= *prev
);
192 /* Move it to the dead table */
195 t
->next
= nvram_dead
;
202 /* Get all NVRAM variables. Should be locked. */
204 _nvram_getall(char *buf
, int count
)
207 struct nvram_tuple
*t
;
212 /* Write name=value\0 ... \0\0 */
213 for (i
= 0; i
< ARRAYSIZE(nvram_hash
); i
++) {
214 for (t
= nvram_hash
[i
]; t
; t
= t
->next
) {
215 if ((count
- len
) > (strlen(t
->name
) + 1 + strlen(t
->value
) + 1))
216 len
+= sprintf(buf
+ len
, "%s=%s", t
->name
, t
->value
) + 1;
225 /* Regenerate NVRAM. Should be locked. */
227 _nvram_commit(struct nvram_header
*header
)
229 char *init
, *config
, *refresh
, *ncdl
;
232 struct nvram_tuple
*t
;
233 struct nvram_header tmp
;
236 /* Regenerate header */
237 header
->magic
= NVRAM_MAGIC
;
238 header
->crc_ver_init
= (NVRAM_VERSION
<< 8);
239 if (!(init
= _nvram_get("sdram_init")) ||
240 !(config
= _nvram_get("sdram_config")) ||
241 !(refresh
= _nvram_get("sdram_refresh")) ||
242 !(ncdl
= _nvram_get("sdram_ncdl"))) {
243 header
->crc_ver_init
|= SDRAM_INIT
<< 16;
244 header
->config_refresh
= SDRAM_CONFIG
;
245 header
->config_refresh
|= SDRAM_REFRESH
<< 16;
246 header
->config_ncdl
= 0;
248 header
->crc_ver_init
|= (bcm_strtoul(init
, NULL
, 0) & 0xffff) << 16;
249 header
->config_refresh
= bcm_strtoul(config
, NULL
, 0) & 0xffff;
250 header
->config_refresh
|= (bcm_strtoul(refresh
, NULL
, 0) & 0xffff) << 16;
251 header
->config_ncdl
= bcm_strtoul(ncdl
, NULL
, 0);
254 /* Clear data area */
255 ptr
= (char *) header
+ sizeof(struct nvram_header
);
256 bzero(ptr
, NVRAM_SPACE
- sizeof(struct nvram_header
));
258 /* Leave space for a double NUL at the end */
259 end
= (char *) header
+ NVRAM_SPACE
- 2;
261 /* Write out all tuples */
262 for (i
= 0; i
< ARRAYSIZE(nvram_hash
); i
++) {
263 for (t
= nvram_hash
[i
]; t
; t
= t
->next
) {
264 if ((ptr
+ strlen(t
->name
) + 1 + strlen(t
->value
) + 1) > end
)
266 ptr
+= sprintf(ptr
, "%s=%s", t
->name
, t
->value
) + 1;
270 /* End with a double NUL */
274 header
->len
= ROUNDUP(ptr
- (char *) header
, 4);
276 /* Little-endian CRC8 over the last 11 bytes of the header */
277 tmp
.crc_ver_init
= htol32(header
->crc_ver_init
);
278 tmp
.config_refresh
= htol32(header
->config_refresh
);
279 tmp
.config_ncdl
= htol32(header
->config_ncdl
);
280 crc
= crc8((char *) &tmp
+ 9, sizeof(struct nvram_header
) - 9, CRC8_INIT_VALUE
);
282 /* Continue CRC8 over data bytes */
283 crc
= crc8((char *) &header
[1], header
->len
- sizeof(struct nvram_header
), crc
);
286 header
->crc_ver_init
|= crc
;
288 /* Reinitialize hash table */
289 return nvram_rehash(header
);
292 /* Initialize hash table. Should be locked. */
296 struct nvram_header
*header
;
299 if (!(header
= (struct nvram_header
*) MALLOC(NVRAM_SPACE
))) {
300 printf("nvram_init: out of memory\n");
301 return -12; /* -ENOMEM */
304 if ((ret
= _nvram_read(header
)) == 0 &&
305 header
->magic
== NVRAM_MAGIC
)
306 nvram_rehash(header
);
308 MFREE(header
, NVRAM_SPACE
);
312 /* Free hash table. Should be locked. */
This page took 0.055218 seconds and 5 git commands to generate.