uboot/common/env_dataflash.c
<<
>>
Prefs
   1/*
   2 * LowLevel function for DataFlash environment support
   3 * Author : Gilles Gastaldi (Atmel)
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License as
   7 * published by the Free Software Foundation; either version 2 of
   8 * the License, or (at your option) any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  18 * MA 02111-1307 USA
  19 */
  20#include <common.h>
  21#include <command.h>
  22#include <environment.h>
  23#include <linux/stddef.h>
  24#include <dataflash.h>
  25#include <search.h>
  26#include <errno.h>
  27
  28DECLARE_GLOBAL_DATA_PTR;
  29
  30env_t *env_ptr;
  31
  32char *env_name_spec = "dataflash";
  33
  34uchar env_get_char_spec(int index)
  35{
  36        uchar c;
  37
  38        read_dataflash(CONFIG_ENV_ADDR + index + offsetof(env_t, data),
  39                        1, (char *)&c);
  40        return c;
  41}
  42
  43void env_relocate_spec(void)
  44{
  45        char buf[CONFIG_ENV_SIZE];
  46
  47        read_dataflash(CONFIG_ENV_ADDR, CONFIG_ENV_SIZE, buf);
  48
  49        env_import(buf, 1);
  50}
  51
  52#ifdef CONFIG_ENV_OFFSET_REDUND
  53#error No support for redundant environment on dataflash yet!
  54#endif
  55
  56int saveenv(void)
  57{
  58        env_t   env_new;
  59        ssize_t len;
  60        char    *res;
  61
  62        res = (char *)&env_new.data;
  63        len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
  64        if (len < 0) {
  65                error("Cannot export environment: errno = %d\n", errno);
  66                return 1;
  67        }
  68        env_new.crc = crc32(0, env_new.data, ENV_SIZE);
  69
  70        return write_dataflash(CONFIG_ENV_ADDR,
  71                                (unsigned long)&env_new,
  72                                CONFIG_ENV_SIZE);
  73}
  74
  75/*
  76 * Initialize environment use
  77 *
  78 * We are still running from ROM, so data use is limited.
  79 * Use a (moderately small) buffer on the stack
  80 */
  81int env_init(void)
  82{
  83        ulong crc, len = ENV_SIZE, new = 0;
  84        unsigned off;
  85        uchar buf[64];
  86
  87        if (gd->env_valid)
  88                return 0;
  89
  90        AT91F_DataflashInit();  /* prepare for DATAFLASH read/write */
  91
  92        /* read old CRC */
  93        read_dataflash(CONFIG_ENV_ADDR + offsetof(env_t, crc),
  94                sizeof(ulong), (char *)&crc);
  95
  96        off = offsetof(env_t, data);
  97        while (len > 0) {
  98                int n = (len > sizeof(buf)) ? sizeof(buf) : len;
  99
 100                read_dataflash(CONFIG_ENV_ADDR + off, n, (char *)buf);
 101
 102                new = crc32(new, buf, n);
 103                len -= n;
 104                off += n;
 105        }
 106
 107        if (crc == new) {
 108                gd->env_addr    = offsetof(env_t, data);
 109                gd->env_valid   = 1;
 110        } else {
 111                gd->env_addr    = (ulong)&default_environment[0];
 112                gd->env_valid   = 0;
 113        }
 114
 115        return 0;
 116}
 117