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