summaryrefslogtreecommitdiff
path: root/src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram/nvram.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram/nvram.c')
-rw-r--r--src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram/nvram.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram/nvram.c b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram/nvram.c
new file mode 100644
index 0000000000..e6a293b029
--- /dev/null
+++ b/src/mainboard/motorola/sandpointx3_altimus_mpc7410/nvram/nvram.c
@@ -0,0 +1,101 @@
+/* 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();
+}
+