Annotation of qemu/roms/openbios/packages/nvram.c, revision 1.1.1.1

1.1       root        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 ([email protected])
                     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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.