~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/openbios/packages/nvram.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *   Creation Date: <2003/12/01 00:26:13 samuel>
 
3
 *   Time-stamp: <2004/01/07 19:59:53 samuel>
 
4
 *
 
5
 *      <nvram.c>
 
6
 *
 
7
 *      medium-level NVRAM handling
 
8
 *
 
9
 *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se)
 
10
 *
 
11
 *   This program is free software; you can redistribute it and/or
 
12
 *   modify it under the terms of the GNU General Public License
 
13
 *   version 2
 
14
 *
 
15
 */
 
16
 
 
17
#include "config.h"
 
18
#include "libopenbios/bindings.h"
 
19
#include "arch/common/nvram.h"
 
20
#include "packages/nvram.h"
 
21
 
 
22
//#define CONFIG_DEBUG_NVRAM 1
 
23
 
 
24
#ifdef CONFIG_DEBUG_NVRAM
 
25
#define DPRINTF(fmt, args...) \
 
26
do { printk("NVRAM: " fmt , ##args); } while (0)
 
27
#else
 
28
#define DPRINTF(fmt, args...) do {} while(0)
 
29
#endif
 
30
 
 
31
#define DEF_SYSTEM_SIZE 0xc10
 
32
 
 
33
#define NV_SIG_SYSTEM   0x70
 
34
#define NV_SIG_FREE     0x7f
 
35
 
 
36
 
 
37
typedef struct {
 
38
        unsigned char   signature;
 
39
        unsigned char   checksum;
 
40
        unsigned char   len_hi;
 
41
        unsigned char   len_lo;
 
42
        char            name[12];
 
43
        char            data[0];
 
44
} nvpart_t;
 
45
 
 
46
static struct {
 
47
        char            *data;
 
48
        int             size;
 
49
 
 
50
        nvpart_t        *config;
 
51
        int             config_size;
 
52
} nvram;
 
53
 
 
54
 
 
55
/************************************************************************/
 
56
/*      generic                                                         */
 
57
/************************************************************************/
 
58
 
 
59
static unsigned int
 
60
nvpart_checksum( nvpart_t* hdr )
 
61
{
 
62
        unsigned char *p = (unsigned char*)hdr;
 
63
        int i, val = p[0];
 
64
 
 
65
        for( i=2; i<16; i++ ) {
 
66
                val += p[i];
 
67
                if( val > 255 )
 
68
                        val = (val - 256 + 1) & 0xff;
 
69
        }
 
70
        return val;
 
71
}
 
72
 
 
73
static inline int
 
74
nvpart_size( nvpart_t *p )
 
75
{
 
76
        return (p->len_lo | ((int)p->len_hi<<8)) * 16;
 
77
}
 
78
 
 
79
static int
 
80
next_nvpart( nvpart_t **p )
 
81
{
 
82
        nvpart_t *end = (nvpart_t*)(nvram.data + nvram.size);
 
83
        int len;
 
84
 
 
85
        if( !*p ) {
 
86
                *p = (nvpart_t*)nvram.data;
 
87
                return 1;
 
88
        }
 
89
 
 
90
        if( !(len=nvpart_size(*p)) ) {
 
91
                printk("invalid nvram partition length\n");
 
92
                return -1;
 
93
        }
 
94
        *p = (nvpart_t*)((char*)*p + len);
 
95
        if( *p < end )
 
96
                return 1;
 
97
        if( *p == end )
 
98
                return 0;
 
99
        return -1;
 
100
}
 
101
 
 
102
static void
 
103
create_free_part( char *ptr, int size )
 
104
{
 
105
        nvpart_t *nvp = (nvpart_t*)ptr;
 
106
        memset( nvp, 0, size );
 
107
 
 
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);
 
113
}
 
114
 
 
115
static int
 
116
create_nv_part( int signature, const char *name, int size )
 
117
{
 
118
        nvpart_t *p = NULL;
 
119
        int fs;
 
120
 
 
121
        while( next_nvpart(&p) > 0 ) {
 
122
                if( p->signature != NV_SIG_FREE )
 
123
                        continue;
 
124
 
 
125
                fs = nvpart_size( p );
 
126
                if( fs < size )
 
127
                        size = fs;
 
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;
 
132
                p->len_lo = size/16;
 
133
                p->checksum = nvpart_checksum(p);
 
134
                if( fs > size ) {
 
135
                        char *fp = (char*)p + size;
 
136
                        create_free_part( fp, fs-size );
 
137
                }
 
138
                return size;
 
139
        }
 
140
        printk("create-failed\n");
 
141
        return -1;
 
142
}
 
143
 
 
144
static void
 
145
zap_nvram( void )
 
146
{
 
147
        create_free_part( nvram.data, nvram.size );
 
148
        create_nv_part( NV_SIG_SYSTEM, "common", DEF_SYSTEM_SIZE );
 
149
}
 
150
 
 
151
#if 0
 
152
static void
 
153
show_partitions( void )
 
154
{
 
155
        nvpart_t *p = NULL;
 
156
        char buf[13];
 
157
 
 
158
        while( next_nvpart(&p) > 0 ) {
 
159
                memcpy( buf, p->name, sizeof(p->name) );
 
160
                buf[12] = 0;
 
161
                printk("[%02x] %-13s:  %03x\n",
 
162
                       p->signature, buf, nvpart_size(p));
 
163
        }
 
164
}
 
165
#endif
 
166
 
 
167
void
 
168
update_nvram( void )
 
169
{
 
170
        PUSH( pointer2cell(nvram.config->data) );
 
171
        PUSH( nvram.config_size );
 
172
        fword("nvram-store-configs");
 
173
        arch_nvram_put( nvram.data );
 
174
}
 
175
 
 
176
void
 
177
nvconf_init( void )
 
178
{
 
179
        int once=0;
 
180
 
 
181
        /* initialize nvram structure completely */
 
182
        nvram.config = NULL;
 
183
        nvram.config_size = 0;
 
184
 
 
185
        nvram.size = arch_nvram_size();
 
186
        nvram.data = malloc( nvram.size );
 
187
        arch_nvram_get( nvram.data );
 
188
 
 
189
        bind_func( "update-nvram", update_nvram );
 
190
 
 
191
        for( ;; ) {
 
192
                nvpart_t *p = NULL;
 
193
                int err;
 
194
 
 
195
                while( (err=next_nvpart(&p)) > 0 ) {
 
196
                        if( nvpart_checksum(p) != p->checksum ) {
 
197
                                err = -1;
 
198
                                break;
 
199
                        }
 
200
                        if( p->signature == NV_SIG_SYSTEM ) {
 
201
                                nvram.config = p;
 
202
                                nvram.config_size = nvpart_size(p) - 0x10;
 
203
 
 
204
                                if( !once++ ) {
 
205
                                        PUSH( pointer2cell(p->data) );
 
206
                                        PUSH( nvram.config_size );
 
207
                                        fword("nvram-load-configs");
 
208
                                }
 
209
                        }
 
210
                }
 
211
                if( err || !nvram.config ) {
 
212
                        printk("nvram error detected, zapping pram\n");
 
213
                        zap_nvram();
 
214
                        if( !once++ )
 
215
                                fword("set-defaults");
 
216
                        continue;
 
217
                }
 
218
                break;
 
219
        }
 
220
}
 
221
 
 
222
 
 
223
/************************************************************************/
 
224
/*      nvram                                                           */
 
225
/************************************************************************/
 
226
 
 
227
typedef struct {
 
228
        unsigned int   mark_hi;
 
229
        unsigned int   mark_lo;
 
230
} nvram_ibuf_t;
 
231
 
 
232
DECLARE_UNNAMED_NODE( nvram, INSTALL_OPEN, sizeof(nvram_ibuf_t ));
 
233
 
 
234
/* ( pos_lo pos_hi -- status ) */
 
235
static void
 
236
nvram_seek( nvram_ibuf_t *nd )
 
237
{
 
238
        int pos_hi = POP();
 
239
        int pos_lo = POP();
 
240
 
 
241
        DPRINTF("seek %08x %08x\n", pos_hi, pos_lo );
 
242
        nd->mark_lo = pos_lo;
 
243
        nd->mark_hi = pos_hi;
 
244
 
 
245
        if( nd->mark_lo >= nvram.size ) {
 
246
                PUSH(-1);
 
247
                return;
 
248
        }
 
249
 
 
250
        /* 0=success, -1=failure (1=legacy success) */
 
251
        PUSH(0);
 
252
}
 
253
 
 
254
/* ( addr len -- actual ) */
 
255
static void
 
256
nvram_read( nvram_ibuf_t *nd )
 
257
{
 
258
        int len = POP();
 
259
        char *p = (char*)cell2pointer(POP());
 
260
        int n=0;
 
261
 
 
262
        while( nd->mark_lo < nvram.size && n < len ) {
 
263
                *p++ = nvram.data[nd->mark_lo++];
 
264
                n++;
 
265
        }
 
266
        PUSH(n);
 
267
        DPRINTF("read %p %x -- %x\n", p, len, n);
 
268
}
 
269
 
 
270
/* ( addr len -- actual ) */
 
271
static void
 
272
nvram_write( nvram_ibuf_t *nd )
 
273
{
 
274
        int len = POP();
 
275
        char *p = (char*)cell2pointer(POP());
 
276
        int n=0;
 
277
 
 
278
        while( nd->mark_lo < nvram.size && n < len ) {
 
279
                nvram.data[nd->mark_lo++] = *p++;
 
280
                n++;
 
281
        }
 
282
        PUSH(n);
 
283
        DPRINTF("write %p %x -- %x\n", p, len, n );
 
284
}
 
285
 
 
286
/* ( -- size ) */
 
287
static void
 
288
nvram_size( __attribute__((unused)) nvram_ibuf_t *nd )
 
289
{
 
290
        DPRINTF("nvram_size %d\n", nvram.size);
 
291
        PUSH( nvram.size );
 
292
}
 
293
 
 
294
NODE_METHODS( nvram ) = {
 
295
        { "size",       (void*)nvram_size       },
 
296
        { "read",       (void*)nvram_read       },
 
297
        { "write",      (void*)nvram_write      },
 
298
        { "seek",       (void*)nvram_seek       },
 
299
};
 
300
 
 
301
 
 
302
void
 
303
nvram_init( const char *path )
 
304
{
 
305
        nvconf_init();
 
306
 
 
307
        REGISTER_NAMED_NODE( nvram, path );
 
308
}