1 /*
2  *  arch/ppc/platforms/prep_nvram.c
3  *
4  *  Copyright (C) 1998  Corey Minyard
5  *
6  */
7 #include <linux/init.h>
8 #include <linux/delay.h>
9 #include <linux/slab.h>
10 #include <linux/ioport.h>
11 
12 #include <asm/sections.h>
13 #include <asm/segment.h>
14 #include <asm/io.h>
15 #include <asm/processor.h>
16 #include <asm/machdep.h>
17 #include <asm/prep_nvram.h>
18 
19 static char nvramData[MAX_PREP_NVRAM];
20 static NVRAM_MAP *nvram=(NVRAM_MAP *)&nvramData[0];
21 
prep_nvram_read_val(int addr)22 unsigned char __prep prep_nvram_read_val(int addr)
23 {
24 	outb(addr, PREP_NVRAM_AS0);
25 	outb(addr>>8, PREP_NVRAM_AS1);
26 	return inb(PREP_NVRAM_DATA);
27 }
28 
prep_nvram_write_val(int addr,unsigned char val)29 void __prep prep_nvram_write_val(int           addr,
30 			  unsigned char val)
31 {
32 	outb(addr, PREP_NVRAM_AS0);
33 	outb(addr>>8, PREP_NVRAM_AS1);
34    	outb(val, PREP_NVRAM_DATA);
35 }
36 
init_prep_nvram(void)37 void __init init_prep_nvram(void)
38 {
39 	unsigned char *nvp;
40 	int  i;
41 	int  nvramSize;
42 
43 	/*
44 	 * The following could fail if the NvRAM were corrupt but
45 	 * we expect the boot firmware to have checked its checksum
46 	 * before boot
47 	 */
48 	nvp = (char *) &nvram->Header;
49 	for (i=0; i<sizeof(HEADER); i++)
50 	{
51 		*nvp = ppc_md.nvram_read_val(i);
52 		nvp++;
53 	}
54 
55 	/*
56 	 * The PReP NvRAM may be any size so read in the header to
57 	 * determine how much we must read in order to get the complete
58 	 * GE area
59 	 */
60 	nvramSize=(int)nvram->Header.GEAddress+nvram->Header.GELength;
61 	if(nvramSize>MAX_PREP_NVRAM)
62 	{
63 		/*
64 		 * NvRAM is too large
65 		 */
66 		nvram->Header.GELength=0;
67 		return;
68 	}
69 
70 	/*
71 	 * Read the remainder of the PReP NvRAM
72 	 */
73 	nvp = (char *) &nvram->GEArea[0];
74 	for (i=sizeof(HEADER); i<nvramSize; i++)
75 	{
76 		*nvp = ppc_md.nvram_read_val(i);
77 		nvp++;
78 	}
79 }
80 
81 __prep
prep_nvram_get_var(const char * name)82 char __prep *prep_nvram_get_var(const char *name)
83 {
84 	char *cp;
85 	int  namelen;
86 
87 	namelen = strlen(name);
88 	cp = prep_nvram_first_var();
89 	while (cp != NULL) {
90 		if ((strncmp(name, cp, namelen) == 0)
91 		    && (cp[namelen] == '='))
92 		{
93 			return cp+namelen+1;
94 		}
95 		cp = prep_nvram_next_var(cp);
96 	}
97 
98 	return NULL;
99 }
100 
101 __prep
prep_nvram_first_var(void)102 char __prep *prep_nvram_first_var(void)
103 {
104         if (nvram->Header.GELength == 0) {
105 		return NULL;
106 	} else {
107 		return (((char *)nvram)
108 			+ ((unsigned int) nvram->Header.GEAddress));
109 	}
110 }
111 
112 __prep
prep_nvram_next_var(char * name)113 char __prep *prep_nvram_next_var(char *name)
114 {
115 	char *cp;
116 
117 
118 	cp = name;
119 	while (((cp - ((char *) nvram->GEArea)) < nvram->Header.GELength)
120 	       && (*cp != '\0'))
121 	{
122 		cp++;
123 	}
124 
125 	/* Skip over any null characters. */
126 	while (((cp - ((char *) nvram->GEArea)) < nvram->Header.GELength)
127 	       && (*cp == '\0'))
128 	{
129 		cp++;
130 	}
131 
132 	if ((cp - ((char *) nvram->GEArea)) < nvram->Header.GELength) {
133 		return cp;
134 	} else {
135 		return NULL;
136 	}
137 }
138 
139 
140 
141