blob: e6a293b029f9fa889f508d9162822b21b635ada8 [file] [log] [blame]
/* Copyright 2000 AG Electronics Ltd. */
/* This code is distributed without warranty under the GPL v2 (see COPYING) */
#include <console/console.h>
#include <stdlib.h>
#include "../nvram.h"
/* NVRAM layout
*
* Environment variable record runs:
* [length]NAME=value[length]NAME=value[0]\0
* A deleted variable is:
* [length]\0AME=value
*
* When memory is full, we compact.
*
*/
static nvram_device *nvram_dev = 0;
static unsigned char *nvram_buffer = 0;
static unsigned nvram_size = 0;
static uint8_t nvram_csum = 0;
#define NVRAM_INVALID (! nvram_dev)
static void update_device(unsigned i, unsigned char data)
{
if (i < nvram_size)
{
nvram_csum -= nvram_buffer[i];
nvram_buffer[i] = data;
nvram_dev->write_byte(nvram_dev, i, data);
nvram_csum += data;
}
else
printk_info("Offset %d out of range in nvram\n", i);
}
static void update_csum(void)
{
nvram_dev->write_byte(nvram_dev, nvram_size, nvram_csum);
if (nvram_dev->commit)
nvram_dev->commit(nvram_dev);
}
static void update_string_device(unsigned i, const unsigned char *data,
unsigned len)
{
if (i + len < nvram_size)
{
unsigned j;
for(j = 0; j < len; j++)
{
nvram_csum -= nvram_buffer[i];
nvram_buffer[i] = *data;
nvram_dev->write_byte(nvram_dev, i, *data);
nvram_csum += *data;
data++;
i++;
}
}
else
printk_info("Offset %d out of range in nvram\n", i + len);
}
int nvram_init (struct nvram_device *dev)
{
nvram_dev = dev;
if (! nvram_size)
nvram_size = dev->size(dev) - 1;
printk_info("NVRAM size is %d\n", nvram_size);
if (!nvram_buffer)
{
unsigned i;
nvram_buffer = malloc (nvram_size);
if (!nvram_buffer)
return -1;
nvram_csum = 0;
dev->read_block(dev, 0, nvram_buffer, nvram_size+1);
for(i = 0; i < nvram_size; i++)
nvram_csum += nvram_buffer[i];
if (nvram_csum != nvram_buffer[nvram_size])
{
printk_info("NVRAM checksum invalid - erasing\n");
//update_device(0, 0);
//update_csum();
}
}
printk_info("Initialised nvram\n");
return 0;
}
void nvram_clear(void)
{
printk_info("Erasing NVRAM\n");
update_device(0, 0);
update_csum();
}