Annotation of qemu/roms/openbios/packages/nvram.c, revision 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.