1 /**************************************************************************
3 * BRIEF MODULE DESCRIPTION
4 * nvram interface routines.
6 * Copyright 2004 IDT Inc. (rischelp@idt.com)
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
14 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
16 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
19 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 **************************************************************************
36 **************************************************************************
39 #include <linux/ctype.h>
40 #include <linux/string.h>
42 //#include <asm/ds1553rtc.h>
44 #define NVRAM_BASE 0xbfff8000
46 extern void setenv (char *e, char *v, int rewrite);
47 extern void unsetenv (char *e);
48 extern void mapenv (int (*func)(char *, char *));
49 extern char *getenv (char *s);
50 extern void purgeenv(void);
52 static void nvram_initenv(void);
55 nvram_getbyte(int offs)
57 return(*((unsigned char*)(NVRAM_BASE + offs)));
61 nvram_setbyte(int offs, unsigned char val)
63 unsigned char* nvramDataPointer = (unsigned char*)(NVRAM_BASE + offs);
65 *nvramDataPointer = val;
72 nvram_getshort(int offs)
74 return((nvram_getbyte(offs) << 8) | nvram_getbyte(offs + 1));
78 nvram_setshort(int offs, unsigned short val)
80 nvram_setbyte(offs, (unsigned char)((val >> 8) & 0xff));
81 nvram_setbyte(offs + 1, (unsigned char)(val & 0xff));
85 nvram_getint(int offs)
88 val = nvram_getbyte(offs) << 24;
89 val |= nvram_getbyte(offs + 1) << 16;
90 val |= nvram_getbyte(offs + 2) << 8;
91 val |= nvram_getbyte(offs + 3);
96 nvram_setint(int offs, unsigned int val)
98 nvram_setbyte(offs, val >> 24);
99 nvram_setbyte(offs + 1, val >> 16);
100 nvram_setbyte(offs + 2, val >> 8);
101 nvram_setbyte(offs + 3, val);
105 * calculate NVRAM checksum
107 static unsigned short
110 unsigned short sum = NV_MAGIC;
113 for (i = ENV_BASE; i < ENV_TOP; i += 2)
114 sum += nvram_getshort(i);
119 * update the nvram checksum
122 nvram_updatesum (void)
124 nvram_setshort(NVOFF_CSUM, nvram_calcsum());
128 * test validity of nvram by checksumming it
138 if (nvram_getshort(NVOFF_MAGIC) != NV_MAGIC) {
139 printk("nvram_isvalid FAILED\n");
146 /* return nvram address of environment string */
148 nvram_matchenv(char *s)
150 int envsize, envp, n, i, varsize;
153 envsize = nvram_getshort(NVOFF_ENVSIZE);
155 if (envsize > ENV_AVAIL)
156 return(0); /* sanity */
160 if ((n = strlen (s)) > 255)
163 while (envsize > 0) {
164 varsize = nvram_getbyte(envp);
165 if (varsize == 0 || (envp + varsize) > ENV_TOP)
166 return(0); /* sanity */
167 for (i = envp + 1, var = s; i <= envp + n; i++, var++) {
168 char c1 = nvram_getbyte(i);
177 if (i > envp + n) { /* match so far */
178 if (n == varsize - 1) /* match on boolean */
180 if (nvram_getbyte(i) == '=') /* exact match on variable */
189 static void nvram_initenv(void)
191 nvram_setshort(NVOFF_MAGIC, NV_MAGIC);
192 nvram_setshort(NVOFF_ENVSIZE, 0);
198 nvram_delenv(char *s)
200 int nenvp, envp, envsize, nbytes;
202 envp = nvram_matchenv(s);
206 nenvp = envp + nvram_getbyte(envp);
207 envsize = nvram_getshort(NVOFF_ENVSIZE);
208 nbytes = envsize - (nenvp - ENV_BASE);
209 nvram_setshort(NVOFF_ENVSIZE, envsize - (nenvp - envp));
211 nvram_setbyte(envp, nvram_getbyte(nenvp));
219 nvram_setenv(char *s, char *v)
224 if (!nvram_isvalid())
239 if (total > 255 || total > ENV_AVAIL - nvram_getshort(NVOFF_ENVSIZE))
242 envp = ENV_BASE + nvram_getshort(NVOFF_ENVSIZE);
244 nvram_setbyte(envp, (unsigned char) total);
248 nvram_setbyte(envp, *s);
254 nvram_setbyte(envp, '=');
257 nvram_setbyte(envp, *v);
262 nvram_setshort(NVOFF_ENVSIZE, envp-ENV_BASE);
268 nvram_getenv(char *s)
270 static char buf[256]; /* FIXME: this cannot be static */
271 int envp, ns, nbytes, i;
273 if (!nvram_isvalid())
274 return "INVALID NVRAM"; //((char *)0);
276 envp = nvram_matchenv(s);
278 return "NOT FOUND"; //((char *)0);
280 if (nvram_getbyte(envp) == ns + 1) /* boolean */
283 nbytes = nvram_getbyte(envp) - (ns + 2);
285 for (i = 0; i < nbytes; i++)
286 buf[i] = nvram_getbyte(envp++);
293 nvram_unsetenv(char *s)
295 if (!nvram_isvalid())
302 * apply func to each string in environment
305 nvram_mapenv(int (*func)(char *, char *))
307 int envsize, envp, n, i, seeneql;
308 char name[256], value[256];
311 if (!nvram_isvalid())
314 envsize = nvram_getshort(NVOFF_ENVSIZE);
317 while (envsize > 0) {
321 n = nvram_getbyte(envp);
322 for (i = envp + 1; i < envp + n; i++) {
323 c = nvram_getbyte(i);
324 if ((c == '=') && !seeneql) {
333 (*func)(name, value);
342 if ('0' <= c && c <= '9')
344 if ('A' <= c && c <= 'Z')
345 return (10 + c - 'A');
346 if ('a' <= c && c <= 'z')
347 return (10 + c - 'a');
352 * Wrappers to allow 'special' environment variables to get processed
355 setenv(char *e, char *v, int rewrite)
357 if (nvram_getenv(e) && !rewrite)
366 return(nvram_getenv(e));
379 unsigned char* nvramDataPointer = (unsigned char*)(NVRAM_BASE);
381 for (i = ENV_BASE; i < ENV_TOP; i++)
382 *nvramDataPointer++ = 0;
383 nvram_setshort(NVOFF_MAGIC, NV_MAGIC);
384 nvram_setshort(NVOFF_ENVSIZE, 0);
385 nvram_setshort(NVOFF_CSUM, NV_MAGIC);
389 mapenv(int (*func)(char *, char *))