[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