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 (mpl@broadcom.com)
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 "lib_types.h"
49#include "lib_string.h"
50#include "lib_queue.h"
51#include "lib_malloc.h"
52#include "lib_printf.h"
53
54#include "cfe_iocb.h"
55#include "cfe_devfuncs.h"
56#include "cfe_ioctl.h"
57
58#include "cfe_error.h"
59#include "env_subr.h"
60#include "nvram_subr.h"
61#include "cfe.h"
62
63/*  *********************************************************************
64    *  Globals
65    ********************************************************************* */
66
67static int nvram_handle = -1;
68static nvram_info_t nvram_info;
69static char *nvram_devname = NULL;
70
71/*  *********************************************************************
72    *  nvram_getinfo(info)
73    *
74    *  Obtain information about the NVRAM device from the device
75    *  driver.  A flash device might only dedicate a single sector
76    *  to the environment, so we need to ask the driver first.
77    *
78    *  Input parameters:
79    *  	   info - nvram info
80    *
81    *  Return value:
82    *  	   0 if ok
83    *  	   <0 = error code
84    ********************************************************************* */
85
86static int nvram_getinfo(nvram_info_t *info)
87{
88    int retlen;
89
90    if (nvram_handle == -1) return -1;
91
92    cfe_ioctl(nvram_handle,IOCTL_NVRAM_UNLOCK,NULL,0,NULL,0);
93
94    if (cfe_ioctl(nvram_handle,IOCTL_NVRAM_GETINFO,
95		  (unsigned char *) info,
96		  sizeof(nvram_info_t),
97		  &retlen,0) != 0) {
98	return -1;
99	}
100
101    return 0;
102
103}
104
105/*  *********************************************************************
106    *  nvram_open()
107    *
108    *  Open the default NVRAM device and get the information from the
109    *  device driver.
110    *
111    *  Input parameters:
112    *  	   nothing
113    *
114    *  Return value:
115    *  	   0 if ok
116    *  	   else error code
117    ********************************************************************* */
118
119int nvram_open(void)
120{
121    if (nvram_handle != -1) {
122	nvram_close();
123	}
124
125    if (nvram_devname == NULL) {
126	return CFE_ERR_DEVNOTFOUND;
127	}
128
129    nvram_handle = cfe_open(nvram_devname);
130
131    if (nvram_handle < 0) {
132	return CFE_ERR_DEVNOTFOUND;
133	}
134
135    if (nvram_getinfo(&nvram_info) < 0) {
136	nvram_close();
137	return CFE_ERR_IOERR;
138	}
139
140    return 0;
141}
142
143/*  *********************************************************************
144    *  nvram_close()
145    *
146    *  Close the NVRAM device
147    *
148    *  Input parameters:
149    *  	   nothing
150    *
151    *  Return value:
152    *  	   0
153    ********************************************************************* */
154
155int nvram_close(void)
156{
157    if (nvram_handle != -1) {
158	cfe_close(nvram_handle);
159	nvram_handle = -1;
160	}
161
162    return 0;
163}
164
165
166/*  *********************************************************************
167    *  nvram_getsize()
168    *
169    *  Return the total size of the NVRAM device.  Note that
170    *  this is the total size that is used for the NVRAM functions,
171    *  not the size of the underlying media.
172    *
173    *  Input parameters:
174    *  	   nothing
175    *
176    *  Return value:
177    *  	   size.  <0 if error
178    ********************************************************************* */
179
180int nvram_getsize(void)
181{
182    if (nvram_handle < 0) return 0;
183    return nvram_info.nvram_size;
184}
185
186
187/*  *********************************************************************
188    *  nvram_read(buffer,offset,length)
189    *
190    *  Read data from the NVRAM device
191    *
192    *  Input parameters:
193    *  	   buffer - destination buffer
194    *  	   offset - offset of data to read
195    *  	   length - number of bytes to read
196    *
197    *  Return value:
198    *  	   number of bytes read, or <0 if error occured
199    ********************************************************************* */
200int nvram_read(unsigned char *buffer,int offset,int length)
201{
202    if (nvram_handle == -1) return -1;
203
204    return cfe_readblk(nvram_handle,
205		       (cfe_offset_t) (offset+nvram_info.nvram_offset),
206		       buffer,
207		       length);
208}
209
210/*  *********************************************************************
211    *  nvram_write(buffer,offset,length)
212    *
213    *  Write data to the NVRAM device
214    *
215    *  Input parameters:
216    *  	   buffer - source buffer
217    *  	   offset - offset of data to write
218    *  	   length - number of bytes to write
219    *
220    *  Return value:
221    *  	   number of bytes written, or -1 if error occured
222    ********************************************************************* */
223int nvram_write(unsigned char *buffer,int offset,int length)
224{
225    if (nvram_handle == -1) return -1;
226
227    return cfe_writeblk(nvram_handle,
228			(cfe_offset_t) (offset+nvram_info.nvram_offset),
229			buffer,
230			length);
231}
232
233
234/*  *********************************************************************
235    *  nvram_erase()
236    *
237    *  Erase the NVRAM device.  Not all devices need to be erased,
238    *  but flash memory does.
239    *
240    *  Input parameters:
241    *  	   nothing
242    *
243    *  Return value:
244    *  	   0 if ok
245    *  	   else error code
246    ********************************************************************* */
247
248int nvram_erase(void)
249{
250    int retlen;
251
252    if (nvram_handle < 0) {
253	return -1;
254	}
255
256    if (nvram_info.nvram_eraseflg == FALSE) return 0;
257
258    if (cfe_ioctl(nvram_handle,IOCTL_NVRAM_ERASE,
259		  (unsigned char *) &nvram_info,
260		  sizeof(nvram_info_t),
261		  &retlen,0) != 0) {
262	return -1;
263	}
264
265    return 0;
266}
267
268
269/*  *********************************************************************
270    *  cfe_set_envdevice(name)
271    *
272    *  Set the environment NVRAM device name
273    *
274    *  Input parameters:
275    *  	   name - name of device to use for NVRAM
276    *
277    *  Return value:
278    *  	   0 if ok
279    *  	   else error code
280    ********************************************************************* */
281
282int cfe_set_envdevice(char *name)
283{
284    int res;
285
286    nvram_devname = strdup(name);
287
288    res = nvram_open();
289
290    if (res != 0) {
291	xprintf("!! Could not open NVRAM device %s\n",nvram_devname);
292	return res;
293	}
294
295    nvram_close();
296
297    res = env_load();
298
299    return res;
300}
301