2 * Creation Date: <2003/12/01 00:26:13 samuel>
3 * Time-stamp: <2004/01/07 19:59:53 samuel>
7 * medium-level NVRAM handling
9 * Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se)
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
18 #include "libopenbios/bindings.h"
19 #include "arch/common/nvram.h"
20 #include "packages/nvram.h"
22 //#define CONFIG_DEBUG_NVRAM 1
24 #ifdef CONFIG_DEBUG_NVRAM
25 #define DPRINTF(fmt, args...) \
26 do { printk("NVRAM: " fmt , ##args); } while (0)
28 #define DPRINTF(fmt, args...) do {} while(0)
31 #define DEF_SYSTEM_SIZE 0xc10
33 #define NV_SIG_SYSTEM 0x70
34 #define NV_SIG_FREE 0x7f
38 unsigned char signature
;
39 unsigned char checksum
;
55 /************************************************************************/
57 /************************************************************************/
60 nvpart_checksum( nvpart_t
* hdr
)
62 unsigned char *p
= (unsigned char*)hdr
;
65 for( i
=2; i
<16; i
++ ) {
68 val
= (val
- 256 + 1) & 0xff;
74 nvpart_size( nvpart_t
*p
)
76 return (p
->len_lo
| ((int)p
->len_hi
<<8)) * 16;
80 next_nvpart( nvpart_t
**p
)
82 nvpart_t
*end
= (nvpart_t
*)(nvram
.data
+ nvram
.size
);
86 *p
= (nvpart_t
*)nvram
.data
;
90 if( !(len
=nvpart_size(*p
)) ) {
91 printk("invalid nvram partition length\n");
94 *p
= (nvpart_t
*)((char*)*p
+ len
);
103 create_free_part( char *ptr
, int size
)
105 nvpart_t
*nvp
= (nvpart_t
*)ptr
;
106 memset( nvp
, 0, size
);
108 strncpy( nvp
->name
, "777777777777", sizeof(nvp
->name
) );
109 nvp
->signature
= NV_SIG_FREE
;
110 nvp
->len_hi
= (size
/16) >> 8;
111 nvp
->len_lo
= size
/16;
112 nvp
->checksum
= nvpart_checksum(nvp
);
116 create_nv_part( int signature
, const char *name
, int size
)
121 while( next_nvpart(&p
) > 0 ) {
122 if( p
->signature
!= NV_SIG_FREE
)
125 fs
= nvpart_size( p
);
128 p
->signature
= signature
;
129 memset( p
->name
, 0, sizeof(p
->name
) );
130 strncpy( p
->name
, name
, sizeof(p
->name
) );
131 p
->len_hi
= (size
>>8)/16;
133 p
->checksum
= nvpart_checksum(p
);
135 char *fp
= (char*)p
+ size
;
136 create_free_part( fp
, fs
-size
);
140 printk("create-failed\n");
147 create_free_part( nvram
.data
, nvram
.size
);
148 create_nv_part( NV_SIG_SYSTEM
, "common", DEF_SYSTEM_SIZE
);
153 show_partitions( void )
158 while( next_nvpart(&p
) > 0 ) {
159 memcpy( buf
, p
->name
, sizeof(p
->name
) );
161 printk("[%02x] %-13s: %03x\n",
162 p
->signature
, buf
, nvpart_size(p
));
170 PUSH( pointer2cell(nvram
.config
->data
) );
171 PUSH( nvram
.config_size
);
172 fword("nvram-store-configs");
173 arch_nvram_put( nvram
.data
);
181 /* initialize nvram structure completely */
183 nvram
.config_size
= 0;
185 nvram
.size
= arch_nvram_size();
186 nvram
.data
= malloc( nvram
.size
);
187 arch_nvram_get( nvram
.data
);
189 bind_func( "update-nvram", update_nvram
);
195 while( (err
=next_nvpart(&p
)) > 0 ) {
196 if( nvpart_checksum(p
) != p
->checksum
) {
200 if( p
->signature
== NV_SIG_SYSTEM
) {
202 nvram
.config_size
= nvpart_size(p
) - 0x10;
205 PUSH( pointer2cell(p
->data
) );
206 PUSH( nvram
.config_size
);
207 fword("nvram-load-configs");
211 if( err
|| !nvram
.config
) {
212 printk("nvram error detected, zapping pram\n");
215 fword("set-defaults");
223 /************************************************************************/
225 /************************************************************************/
228 unsigned int mark_hi
;
229 unsigned int mark_lo
;
232 DECLARE_UNNAMED_NODE( nvram
, INSTALL_OPEN
, sizeof(nvram_ibuf_t
));
234 /* ( pos_lo pos_hi -- status ) */
236 nvram_seek( nvram_ibuf_t
*nd
)
241 DPRINTF("seek %08x %08x\n", pos_hi
, pos_lo
);
242 nd
->mark_lo
= pos_lo
;
243 nd
->mark_hi
= pos_hi
;
245 if( nd
->mark_lo
>= nvram
.size
) {
250 /* 0=success, -1=failure (1=legacy success) */
254 /* ( addr len -- actual ) */
256 nvram_read( nvram_ibuf_t
*nd
)
259 char *p
= (char*)cell2pointer(POP());
262 while( nd
->mark_lo
< nvram
.size
&& n
< len
) {
263 *p
++ = nvram
.data
[nd
->mark_lo
++];
267 DPRINTF("read %p %x -- %x\n", p
, len
, n
);
270 /* ( addr len -- actual ) */
272 nvram_write( nvram_ibuf_t
*nd
)
275 char *p
= (char*)cell2pointer(POP());
278 while( nd
->mark_lo
< nvram
.size
&& n
< len
) {
279 nvram
.data
[nd
->mark_lo
++] = *p
++;
283 DPRINTF("write %p %x -- %x\n", p
, len
, n
);
288 nvram_size( __attribute__((unused
)) nvram_ibuf_t
*nd
)
290 DPRINTF("nvram_size %d\n", nvram
.size
);
294 NODE_METHODS( nvram
) = {
295 { "size", (void*)nvram_size
},
296 { "read", (void*)nvram_read
},
297 { "write", (void*)nvram_write
},
298 { "seek", (void*)nvram_seek
},
303 nvram_init( const char *path
)
307 REGISTER_NAMED_NODE( nvram
, path
);