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 );