[U-Boot-Users] [PATCH 8/11] Add support for environment storage in SystemACE

Keith J Outwater kjoutwater at raytheon.com
Fri May 5 20:15:05 CEST 2006


The patch below adds support for storing the U-Boot environment in a 
Compact FLASH card attached to a Xilinx SystemACE controller.  The ability 
to store the environment in a CF card is useful in situations where 
conventional board-mounted FLASH memory is unavailable.  Note that this 
option requires SystemACE CF write support which is presently not in 
U-Boot.

I will submit a patch to Wolfgang Denk directly (due to list attachment 
size limits) which provides board-specific (ant2 board) support for CF 
writes.

diff --git a/CHANGELOG b/CHANGELOG
index c774dd0..d26e65f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,11 @@
 Changes since U-Boot 1.1.4:
 ======================================================================
 
+* Add support for storing environment on a Compact Flash card managed
+  by a Xilinx SystemACE controller.  The environment is stored on a
+  dedicated, unformatted partition on the card.
+  Patch by Keith Outwater, 04 May 2006
+
 * Coding Style cleanup
 
 * Write RTC seconds first to maintain settings integrity per
diff --git a/CREDITS b/CREDITS
index f91fa3e..0ff1ef2 100644
--- a/CREDITS
+++ b/CREDITS
@@ -326,8 +326,9 @@ E: torkun at nextio.com
 D: Support for Cogent CSB272 & CSB472 boards
 
 N: Keith Outwater
-E: keith_outwater at mvis.com
+E: outwater4 at comcast.net
 D: Support for generic/custom MPC860T boards (GEN860T, GEN860T_SC)
+D: Support for environment storage in SystemACE Compact FLASH
 
 N: Frank Panno
 E: fpanno at delphintech.com
diff --git a/README b/README
index 3ffef62..e1ba798 100644
--- a/README
+++ b/README
@@ -1535,6 +1535,15 @@ The following options need to be configu
                When SystemACE support is added, the "ace" device type
                becomes available to the fat commands, i.e. fatls.
 
+               CFG_USE_BSP_SYSACE_DRIVER
+
+               Defining this option selects board specific functions
+               for accessing the CF card attached to the SystemACE
+               controller.  Typically the drivers would be based on the
+               Xilinx drivers generated by the Xilinx EDK tool.
+               The Xilinx driver can handle both 8 and 16 bit databus
+               interfaces to the SystemACE controller.
+
 - TFTP Fixed UDP Port:
                CONFIG_TFTP_PORT
 
@@ -1995,6 +2004,27 @@ to save the current settings.
        to a block boundary, and CFG_ENV_SIZE must be a multiple of
        the NAND devices block size.
 
+- CFG_ENV_IS_IN_SYSACE:
+
+       Define this if you have a Compact Flash (CF) card connected to a
+       Xilinx SystemACE controller in which you wish to store the 
environment.
+
+       - CFG_SYSTEMACE_ENV_DEV:
+       The device (instance) number of the SystemACE device you wich to 
use.
+       This is normally zero for a system with a single SystemACE.
+
+       - CFG_ENV_SIZE:
+       The size of the environment in bytes.  Note that presently this 
must
+       be a multiple of the CF card sector size (512 bytes).
+
+       - CFG_SYSTEMACE_ENV_PART:
+       The partiton number of the partition dedicated to U-Boot 
environment
+       storage.  You need to insure that the partiton includes enough
+       sectors to store the environment.  The partition must be a primary
+       partition and the partition must be used exclusively for the
+       environment.
+
+
 - CFG_SPI_INIT_OFFSET
 
        Defines offset to the initial SPI buffer area in DPRAM. The
diff --git a/common/Makefile b/common/Makefile
index eb0b5da..04b5b9b 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -44,7 +44,7 @@ COBJS = main.o ACEX1K.o altera.o bedbug.
          command.o console.o devices.o dlmalloc.o docecc.o \
          environment.o env_common.o \
          env_nand.o env_dataflash.o env_flash.o env_eeprom.o \
-         env_nvram.o env_nowhere.o \
+         env_nvram.o env_sysace.o env_nowhere.o \
          exports.o \
          flash.o fpga.o ft_build.o \
          hush.o kgdb.o lcd.o lists.o lynxkdi.o \
diff --git a/common/cmd_ace.c b/common/cmd_ace.c
index b6d6105..ba6d0fe 100644
--- a/common/cmd_ace.c
+++ b/common/cmd_ace.c
@@ -32,6 +32,13 @@ #ident "$Id:$"
  * description that has all the bits needed for FAT support to
  * read sectors.
  *
+ * If CFG_USE_BSP_SYSACE_DRIVER is defined, use a board
+ * specific SystemACE driver to access the CF card. Typically
+ * the BSP driver would use the Xilinx driver code generated by
+ * the Xilinx EDK tool.  The Xilinx SystemACE driver
+ * automatically handles endian conversion and 8 or 16 bit
+ * SystemACE databus widths.
+ *
  * According to Xilinx technical support, before accessing the
  * SystemACE CF you need to set the following control bits:
  *     FORCECFGMODE : 1
@@ -45,7 +52,8 @@ # include  <systemace.h>
 # include  <part.h>
 # include  <asm/io.h>
 
-#ifdef CONFIG_SYSTEMACE
+#if defined(CONFIG_SYSTEMACE)
+#if !defined(CFG_USE_BSP_SYSACE_DRIVER)
 
 /*
  * The ace_readw and writew functions read/write 16bit words, but the
@@ -264,4 +272,5 @@ #endif
 
       return blkcnt;
 }
-#endif /* CONFIG_SYSTEMACE */
+#endif /* !defined(CFG_USE_BSP_SYSACE_DRIVER) */
+#endif /* defined(CONFIG_SYSTEMACE) */
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 6257fbd..0985509 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -57,6 +57,7 @@ #if !defined(CFG_ENV_IS_IN_NVRAM)     && \
     !defined(CFG_ENV_IS_IN_FLASH)      && \
     !defined(CFG_ENV_IS_IN_DATAFLASH)  && \
     !defined(CFG_ENV_IS_IN_NAND)       && \
+    !defined(CFG_ENV_IS_IN_SYSTEMACE)  && \
     !defined(CFG_ENV_IS_NOWHERE)
 # error Define one of 
CFG_ENV_IS_IN_{NVRAM|EEPROM|FLASH|DATAFLASH|NOWHERE}
 #endif
@@ -530,7 +531,9 @@ int getenv_r (char *name, char *buf, uns
        return (-1);
 }
 
-#if defined(CFG_ENV_IS_IN_NVRAM) || defined(CFG_ENV_IS_IN_EEPROM) || \
+#if defined(CFG_ENV_IS_IN_NVRAM) || \
+    defined(CFG_ENV_IS_IN_EEPROM) || \
+    defined(CFG_ENV_IS_IN_SYSTEMACE) || \
     ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == \
       (CFG_CMD_ENV|CFG_CMD_FLASH)) || \
     ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_NAND)) == \
@@ -588,7 +591,9 @@ U_BOOT_CMD(
        "    - delete environment variable 'name'\n"
 );
 
-#if defined(CFG_ENV_IS_IN_NVRAM) || defined(CFG_ENV_IS_IN_EEPROM) || \
+#if defined(CFG_ENV_IS_IN_NVRAM) || \
+    defined(CFG_ENV_IS_IN_EEPROM) || \
+    defined(CFG_ENV_IS_IN_SYSTEMACE) || \
     ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == \
       (CFG_CMD_ENV|CFG_CMD_FLASH)) || \
     ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_NAND)) == \
diff --git a/common/env_common.c b/common/env_common.c
index eb33422..492f979 100644
--- a/common/env_common.c
+++ b/common/env_common.c
@@ -141,7 +141,8 @@ #endif
        "\0"
 };
 
-#if defined(CFG_ENV_IS_IN_NAND)                /* Environment is in Nand 
Flash */
+/* Environment is in Nand Flash or in CF card attached to a SystemACE*/
+#if defined(CFG_ENV_IS_IN_NAND) || defined (CFG_ENV_IS_IN_SYSTEMACE)
 int default_environment_size = sizeof(default_environment);
 #endif
 
diff --git a/common/env_sysace.c b/common/env_sysace.c
new file mode 100644
index 0000000..616519c
--- /dev/null
+++ b/common/env_sysace.c
@@ -0,0 +1,268 @@
+/*-------------------------------------------------------------------- 
+ * (C) Copyright 2005
+ * Keith Outwater, outwater4 at comcast.net
+ *
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Support for saving the U-Boot environment in a CompactFlash card 
connected
+ * to a Xilinx SystemACE FPGA configuration engine.
+ * 
+ * The basic approach used here is to get just enough of a default
+ * environment to be able to get the console serial port baud rate set up
+ * and then get the full environment after U-Boot relocates into main 
memory.
+ * After relocation, there is a full C environment available, so we can 
use
+ * the existing code to load/store the environment onto a dedicated 
partition
+ * on the CF card. If we had FAT filesystem code to do writes instead of 
just
+ * reads, we could even store the environment as a regular DOS file. 
Alas,
+ * we do not have that code...
+ */
+
+#include <common.h>
+
+#if defined(CFG_ENV_IS_IN_SYSTEMACE) 
+
+#if !defined(CFG_SYSTEMACE_ENV_DEV)
+#error "You must specify the SystemACE device instance"
+#endif
+
+#if !defined(CFG_SYSTEMACE_ENV_PART)
+#error "You must specify a primary partition 1-4 for the environment"
+#endif
+
+#include <command.h>
+#include <environment.h>
+#include <linux/stddef.h>
+#include <malloc.h>
+#include "../disk/part_dos.h"  /* ugly, but it's not in ../include! */
+
+/*
+ * This function can be either board-specific or U-Boot builtin
+ */
+extern unsigned long systemace_read(int dev, unsigned long start,
+ lbaint_t blkcnt,
+ unsigned long *buffer);
+
+/*
+ * Presently this function is board-specific only (ant2)
+ */
+extern unsigned long systemace_write(int dev, unsigned long start,
+ lbaint_t blkcnt,
+ unsigned long *buffer);
+
+/*
+ * In env_common.c
+ */
+extern uchar default_environment[];
+extern int default_environment_size;
+
+env_t *env_ptr = NULL;
+char *env_name_spec = "SystemACE";
+
+#define        CF_SECT_SIZE    512
+#define        CF_ENV_SECTS    (CFG_ENV_SIZE / CF_SECT_SIZE)
+
+uchar
+env_get_char_spec(int index)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       return ( *((uchar *)(gd->env_addr + index)) );
+}
+
+static inline int
+le32_to_int(unsigned char *le32)
+{
+    return ((le32[3] << 24) + (le32[2] << 16) + (le32[1] << 8) + 
le32[0]);
+}
+
+/*
+ * Read the CF card partition table and determine the absolute starting
+ * sector for the partition and the size in sectors of the partition.
+ * Return 1 on error, 0 on success.
+ */
+static int
+read_env_partition(int *start)
+{
+       int     start_sect;
+       int     sect_size;
+       u_char  buffer[CF_SECT_SIZE];
+       dos_partition_t *pt;
+
+       /*
+        * Read the partition table and get the first sector of the 
environment
+        * partition.
+        */
+       if (systemace_read(CFG_SYSTEMACE_ENV_DEV, 0, 1,
+                                          (unsigned long *)buffer) != 1) 
{
+               puts("Error reading partiton table\n"); 
+               return 1;
+       }
+
+#if (CFG_SYSTEMACE_ENV_PART < 1) || (CFG_SYSTEMACE_ENV_PART > 4)
+#error "The partition number must be between 1 and 4"
+#endif
+
+       /*
+        * Index into the partition table to get to the partition reserved 
for
+        * the U-Boot environment as specified in the board configuration.
+        */
+       pt = (dos_partition_t *)(buffer + DOS_PART_TBL_OFFSET +
+                               (sizeof(dos_partition_t) * 
(CFG_SYSTEMACE_ENV_PART - 1)));
+
+       start_sect = le32_to_int(pt->start4);
+       sect_size = le32_to_int(pt->size4);
+
+       /*
+        * Basic sanity check: is the starting sector greator than zero 
and is
+        * the number of sectors in the partition enough to hold the 
environment?
+        */
+       if (start_sect <= 0) {
+               puts("Error: Starting sector in partition is not 
positive\n");
+               return 1;
+       }
+ 
+       if ((CF_ENV_SECTS) > sect_size) {
+               printf("Error: Sectors in partition (%d) less than 
required (%d)\n",
+                               sect_size, CF_ENV_SECTS);
+               return 1;
+       }
+
+       *start = start_sect;
+       return 0;
+}
+
+/*
+ * Copy the default environment into the environment.
+ */
+static void
+use_default_env(void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       puts("Using default environment\n");
+
+       if (default_environment_size > CFG_ENV_SIZE){
+               puts("Error: Default environment is too large\n");
+               return;
+       }
+
+       memset (env_ptr, 0, sizeof(env_t));
+       memcpy (env_ptr->data, default_environment, 
default_environment_size);
+       env_ptr->crc = crc32(0, env_ptr->data, ENV_SIZE);
+       gd->env_valid = 1;
+}
+
+/*
+ * This is where we get the "real" environment loaded from the CF card.
+ * We are running in a normal C environemnt at this point (i.e. this is
+ * post U-Boot relocation).
+ */
+void
+env_relocate_spec(void)
+{
+       int     start_sect;
+
+       if (read_env_partition(&start_sect) != 0) {
+               puts("Error: CF card partition table read failed; "); 
+               return use_default_env();
+       }
+ 
+       /*
+        * Read the partition table and get the first sector of the 
environment
+        * partition.
+        */
+       if (systemace_read(CFG_SYSTEMACE_ENV_DEV, (unsigned long) 
start_sect,
+                                          CF_ENV_SECTS,
+                                          (unsigned long *)env_ptr) != 
CF_ENV_SECTS) {
+               puts("Error: CF card read failed; "); 
+               return use_default_env();
+       }
+
+#ifdef DEBUG
+       printf("%s:%d: Start sector = %d\n", __FUNCTION__, __LINE__, 
start_sect); 
+#endif
+
+       /*
+        * If crc fails, use the default environment.
+        */
+       if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc) {
+               puts("Error: CRC failed; ");
+               return use_default_env();
+       }
+}
+
+int
+saveenv(void)
+{
+       int             start_sect;
+
+       if (read_env_partition(&start_sect) != 0) {
+               return 1;
+       }
+
+#ifdef DEBUG
+       printf("%s:%d: Start sector = %d\n", __FUNCTION__, __LINE__, 
start_sect); 
+#endif
+ 
+       /*
+        * We know the absolute start sector on the CF card, so now simply
+        * write the environment to the card.
+        * NOTE that we require the environment to be an integer number of 
CF
+        * card sectors!  It doesn't have to be, but it's convenient and 
it's
+        * not like we'll run out of space on the card...
+        */
+       if (systemace_write(CFG_SYSTEMACE_ENV_DEV, (unsigned 
long)start_sect,
+                                               CF_ENV_SECTS,
+                                               (unsigned long *)env_ptr) 
!= CF_ENV_SECTS) {
+               puts("Error: CF card write failed\n");
+               return 1;
+       }
+       else {
+               puts("Done.\n");
+       }
+
+       return 0;
+}
+
+/*
+ * Initialize the environment.
+ * Still in a "ROM" environment, so just use the default environment.
+ * When env_relocate_spec() gets called from env_relocate()
+ * located in env_common.c, the execution environment will be a
+ * "normal" C environment and we can then read the full environment
+ * from the SystemACE CF card.  Using the default environment will
+ * get us talking to the UART.
+ */
+int
+env_init(void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       gd->env_addr  = (ulong)&default_environment[0];
+       gd->env_valid = 1;
+       return 0;
+}
+
+#endif /* CFG_ENV_IS_IN_SYSTEMACE */
+/* vim: set ts=4 tw=80 sw=4 cindent fo=tcroq: */

Signed-off-by: Keith Outwater <outwater4 at comcast.net>




More information about the U-Boot mailing list