1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  NVRAM subroutines			File: nvram_subr.c
5    *
6    *  High-level routines to read/write the NVRAM device.
7    *
8    *  Author:  Mitch Lichtenberg
9    *
10    *********************************************************************
11    *
12    *  Copyright 2000,2001,2002,2003
13    *  Broadcom Corporation. All rights reserved.
14    *
15    *  This software is furnished under license and may be used and
16    *  copied only in accordance with the following terms and
17    *  conditions.  Subject to these conditions, you may download,
18    *  copy, install, use, modify and distribute modified or unmodified
19    *  copies of this software in source and/or binary form.  No title
20    *  or ownership is transferred hereby.
21    *
22    *  1) Any source code used, modified or distributed must reproduce
23    *     and retain this copyright notice and list of conditions
24    *     as they appear in the source file.
25    *
26    *  2) No right is granted to use any trade name, trademark, or
27    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
28    *     name may not be used to endorse or promote products derived
29    *     from this software without the prior written permission of
30    *     Broadcom Corporation.
31    *
32    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
33    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
34    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
35    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
36    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
37    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
38    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
40    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
42    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
43    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
44    *     THE POSSIBILITY OF SUCH DAMAGE.
45    ********************************************************************* */
46
47
48#include "cfe.h"
49#include "env_subr.h"
50#include "nvram_subr.h"
51
52/*  *********************************************************************
53    *  Globals
54    ********************************************************************* */
55
56static int nvram_handle = -1;
57static nvram_info_t nvram_info;
58static char *nvram_devname = NULL;
59
60/*  *********************************************************************
61    *  nvram_getinfo(info)
62    *
63    *  Obtain information about the NVRAM device from the device
64    *  driver.  A flash device might only dedicate a single sector
65    *  to the environment, so we need to ask the driver first.
66    *
67    *  Input parameters:
68    *  	   info - nvram info
69    *
70    *  Return value:
71    *  	   0 if ok
72    *  	   <0 = error code
73    ********************************************************************* */
74
75static int nvram_getinfo(nvram_info_t *info)
76{
77    int retlen;
78
79    if (nvram_handle == -1) return -1;
80
81    cfe_ioctl(nvram_handle,IOCTL_NVRAM_UNLOCK,NULL,0,NULL,0);
82
83    if (cfe_ioctl(nvram_handle,IOCTL_NVRAM_GETINFO,
84		  (unsigned char *) info,
85		  sizeof(nvram_info_t),
86		  &retlen,0) != 0) {
87	return -1;
88	}
89
90    return 0;
91
92}
93
94/*  *********************************************************************
95    *  nvram_open()
96    *
97    *  Open the default NVRAM device and get the information from the
98    *  device driver.
99    *
100    *  Input parameters:
101    *  	   nothing
102    *
103    *  Return value:
104    *  	   0 if ok
105    *  	   else error code
106    ********************************************************************* */
107
108int nvram_open(void)
109{
110    if (nvram_handle != -1) {
111	nvram_close();
112	}
113
114    if (nvram_devname == NULL) {
115	return CFE_ERR_DEVNOTFOUND;
116	}
117
118    nvram_handle = cfe_open(nvram_devname);
119
120    if (nvram_handle < 0) {
121	return CFE_ERR_DEVNOTFOUND;
122	}
123
124    if (nvram_getinfo(&nvram_info) < 0) {
125	nvram_close();
126	return CFE_ERR_IOERR;
127	}
128
129    return 0;
130}
131
132/*  *********************************************************************
133    *  nvram_close()
134    *
135    *  Close the NVRAM device
136    *
137    *  Input parameters:
138    *  	   nothing
139    *
140    *  Return value:
141    *  	   0
142    ********************************************************************* */
143
144int nvram_close(void)
145{
146    if (nvram_handle != -1) {
147	cfe_close(nvram_handle);
148	nvram_handle = -1;
149	}
150
151    return 0;
152}
153
154
155/*  *********************************************************************
156    *  nvram_getsize()
157    *
158    *  Return the total size of the NVRAM device.  Note that
159    *  this is the total size that is used for the NVRAM functions,
160    *  not the size of the underlying media.
161    *
162    *  Input parameters:
163    *  	   nothing
164    *
165    *  Return value:
166    *  	   size.  <0 if error
167    ********************************************************************* */
168
169int nvram_getsize(void)
170{
171    if (nvram_handle < 0) return 0;
172    return nvram_info.nvram_size;
173}
174
175
176/*  *********************************************************************
177    *  nvram_read(buffer,offset,length)
178    *
179    *  Read data from the NVRAM device
180    *
181    *  Input parameters:
182    *  	   buffer - destination buffer
183    *  	   offset - offset of data to read
184    *  	   length - number of bytes to read
185    *
186    *  Return value:
187    *  	   number of bytes read, or <0 if error occured
188    ********************************************************************* */
189int nvram_read(unsigned char *buffer,int offset,int length)
190{
191    if (nvram_handle == -1) return -1;
192
193    return cfe_readblk(nvram_handle,
194		       (cfe_offset_t) (offset+nvram_info.nvram_offset),
195		       PTR2HSADDR(buffer),
196		       length);
197}
198
199/*  *********************************************************************
200    *  nvram_write(buffer,offset,length)
201    *
202    *  Write data to the NVRAM device
203    *
204    *  Input parameters:
205    *  	   buffer - source buffer
206    *  	   offset - offset of data to write
207    *  	   length - number of bytes to write
208    *
209    *  Return value:
210    *  	   number of bytes written, or -1 if error occured
211    ********************************************************************* */
212int nvram_write(unsigned char *buffer,int offset,int length)
213{
214    if (nvram_handle == -1) return -1;
215
216    return cfe_writeblk(nvram_handle,
217			(cfe_offset_t) (offset+nvram_info.nvram_offset),
218			PTR2HSADDR(buffer),
219			length);
220}
221
222
223/*  *********************************************************************
224    *  nvram_erase()
225    *
226    *  Erase the NVRAM device.  Not all devices need to be erased,
227    *  but flash memory does.
228    *
229    *  Input parameters:
230    *  	   nothing
231    *
232    *  Return value:
233    *  	   0 if ok
234    *  	   else error code
235    ********************************************************************* */
236
237int nvram_erase(void)
238{
239    int retlen;
240
241    if (nvram_handle < 0) {
242	return -1;
243	}
244
245    if (nvram_info.nvram_eraseflg == FALSE) return 0;
246
247    if (cfe_ioctl(nvram_handle,IOCTL_NVRAM_ERASE,
248		  (unsigned char *) &nvram_info,
249		  sizeof(nvram_info_t),
250		  &retlen,0) != 0) {
251	return -1;
252	}
253
254    return 0;
255}
256
257
258/*  *********************************************************************
259    *  cfe_set_envdevice(name)
260    *
261    *  Set the environment NVRAM device name
262    *
263    *  Input parameters:
264    *  	   name - name of device to use for NVRAM
265    *
266    *  Return value:
267    *  	   0 if ok
268    *  	   else error code
269    ********************************************************************* */
270
271int cfe_set_envdevice(char *name)
272{
273    int res;
274
275    nvram_devname = strdup(name);
276
277    res = nvram_open();
278
279    if (res != 0) {
280	xprintf("!! Could not open NVRAM device %s\n",nvram_devname);
281	return res;
282	}
283
284    nvram_close();
285
286    res = env_load();
287
288    return res;
289}
290