Browse Source

Make getenv() work before relocation.

So far, getenv() would work before relocation is most cases, even
though it was not intended to be used that way.  When switching to a
hash table based implementation, this would break a number of boards.

For convenience, we make getenv() check if it's running before
relocation and, if so, use getenv_f() internally.

Note that this is limited to simple cases, as we use a small static
buffer (32 bytes) in the global data for this purpose.

For this reason, it is also not a good idea to convert all current
uses of getenv_f() into getenv() - some of the existing use cases need
to be able to deal with longer variable values, so getenv_f() is still
needed and recommended for use before relocation.

Signed-off-by: Wolfgang Denk <wd@denx.de>
Wolfgang Denk 14 years ago
parent
commit
91a76751a0

+ 3 - 8
arch/arm/include/asm/global_data.h

@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2002
+ * (C) Copyright 2002-2010
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  * See file CREDITS for list of people who contributed to this
@@ -46,14 +46,9 @@ typedef	struct	global_data {
 #endif
 #ifdef CONFIG_FSL_ESDHC
 	unsigned long	sdhc_clk;
-#endif
-#if 0
-	unsigned long	cpu_clk;	/* CPU clock in Hz!		*/
-	unsigned long	bus_clk;
-	phys_size_t	ram_size;	/* RAM size */
-	unsigned long	reset_status;	/* reset status register at boot */
 #endif
 	void		**jt;		/* jump table */
+	char		env_buf[32];	/* buffer for getenv() before reloc. */
 } gd_t;
 
 /*
@@ -65,7 +60,7 @@ typedef	struct	global_data {
 #define	GD_FLG_POSTFAIL	0x00008		/* Critical POST test failed		*/
 #define	GD_FLG_POSTSTOP	0x00010		/* POST seqeunce aborted		*/
 #define	GD_FLG_LOGINIT	0x00020		/* Log Buffer has been initialized	*/
-#define GD_FLG_DISABLE_CONSOLE	0x00040		/* Disable console (in & out)	 */
+#define GD_FLG_DISABLE_CONSOLE	0x00040	/* Disable console (in & out)		*/
 
 #define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8")
 

+ 2 - 1
arch/avr32/include/asm/global_data.h

@@ -46,6 +46,7 @@ typedef	struct	global_data {
 	void		*fb_base;	/* framebuffer address */
 #endif
 	void		**jt;		/* jump table */
+	char		env_buf[32];	/* buffer for getenv() before reloc. */
 } gd_t;
 
 /*
@@ -57,7 +58,7 @@ typedef	struct	global_data {
 #define GD_FLG_POSTFAIL	0x00008		/* Critical POST test failed	 */
 #define GD_FLG_POSTSTOP	0x00010		/* POST seqeunce aborted	 */
 #define GD_FLG_LOGINIT	0x00020		/* Log Buf has been initialized	 */
-#define GD_FLG_DISABLE_CONSOLE	0x00040		/* Disable console (in & out)	 */
+#define GD_FLG_DISABLE_CONSOLE	0x00040	/* Disable console (in & out)	 */
 
 #define DECLARE_GLOBAL_DATA_PTR register gd_t *gd asm("r5")
 

+ 4 - 3
arch/blackfin/include/asm/global_data.h

@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2005-2007 Analog Devices Inc.
  *
- * (C) Copyright 2000-2004
+ * (C) Copyright 2000-2010
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  * See file CREDITS for list of people who contributed to this
@@ -53,7 +53,8 @@ typedef struct global_data {
 	unsigned long post_init_f_time;	/* When post_init_f started */
 #endif
 
-	void **jt;		/* jump table */
+	void	**jt;			/* jump table */
+	char	env_buf[32];		/* buffer for getenv() before reloc. */
 } gd_t;
 
 /*
@@ -65,7 +66,7 @@ typedef struct global_data {
 #define	GD_FLG_POSTFAIL	0x00008	/* Critical POST test failed     */
 #define	GD_FLG_POSTSTOP	0x00010	/* POST seqeunce aborted	 */
 #define	GD_FLG_LOGINIT	0x00020	/* Log Buf has been initialized	 */
-#define GD_FLG_DISABLE_CONSOLE	0x00040		/* Disable console (in & out)	 */
+#define GD_FLG_DISABLE_CONSOLE	0x00040	/* Disable console (in & out)	*/
 
 #define DECLARE_GLOBAL_DATA_PTR     register gd_t * volatile gd asm ("P3")
 

+ 3 - 2
arch/i386/include/asm/global_data.h

@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2002
+ * (C) Copyright 2002-2010
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  * See file CREDITS for list of people who contributed to this
@@ -46,6 +46,7 @@ typedef	struct {
 	phys_size_t	ram_size;	/* RAM size */
 	unsigned long	reset_status;	/* reset status register at boot */
 	void		**jt;		/* jump table */
+	char		env_buf[32];	/* buffer for getenv() before reloc. */
 } gd_t;
 
 /*
@@ -57,7 +58,7 @@ typedef	struct {
 #define	GD_FLG_POSTFAIL	0x00008		/* Critical POST test failed		*/
 #define	GD_FLG_POSTSTOP	0x00010		/* POST seqeunce aborted		*/
 #define	GD_FLG_LOGINIT	0x00020		/* Log Buffer has been initialized	*/
-#define GD_FLG_DISABLE_CONSOLE	0x00040		/* Disable console (in & out)	 */
+#define GD_FLG_DISABLE_CONSOLE	0x00040	/* Disable console (in & out)		*/
 
 extern gd_t *gd;
 

+ 3 - 2
arch/m68k/include/asm/global_data.h

@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2002 - 2003
+ * (C) Copyright 2002 - 2010
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  * See file CREDITS for list of people who contributed to this
@@ -64,6 +64,7 @@ typedef	struct	global_data {
 	unsigned long	board_type;
 #endif
 	void		**jt;		/* Standalone app jump table */
+	char		env_buf[32];	/* buffer for getenv() before reloc. */
 } gd_t;
 
 /*
@@ -75,7 +76,7 @@ typedef	struct	global_data {
 #define	GD_FLG_POSTFAIL	0x00008		/* Critical POST test failed		*/
 #define	GD_FLG_POSTSTOP	0x00010		/* POST seqeunce aborted		*/
 #define	GD_FLG_LOGINIT	0x00020		/* Log Buffer has been initialized	*/
-#define GD_FLG_DISABLE_CONSOLE	0x00040		/* Disable console (in & out)	 */
+#define GD_FLG_DISABLE_CONSOLE	0x00040	/* Disable console (in & out)		*/
 
 #if 0
 extern gd_t *global_data;

+ 2 - 1
arch/microblaze/include/asm/global_data.h

@@ -43,6 +43,7 @@ typedef	struct	global_data {
 	unsigned long	env_valid;	/* Checksum of Environment valid? */
 	unsigned long	fb_base;	/* base address of frame buffer */
 	void		**jt;		/* jump table */
+	char		env_buf[32];	/* buffer for getenv() before reloc. */
 } gd_t;
 
 /*
@@ -54,7 +55,7 @@ typedef	struct	global_data {
 #define	GD_FLG_POSTFAIL	0x00008		/* Critical POST test failed		*/
 #define	GD_FLG_POSTSTOP	0x00010		/* POST seqeunce aborted		*/
 #define	GD_FLG_LOGINIT	0x00020		/* Log Buffer has been initialized	*/
-#define GD_FLG_DISABLE_CONSOLE	0x00040		/* Disable console (in & out)	 */
+#define GD_FLG_DISABLE_CONSOLE	0x00040	/* Disable console (in & out)		*/
 
 #define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r31")
 

+ 3 - 2
arch/mips/include/asm/global_data.h

@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2002-2003
+ * (C) Copyright 2002-2010
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  * See file CREDITS for list of people who contributed to this
@@ -46,6 +46,7 @@ typedef	struct	global_data {
 	unsigned long	env_addr;	/* Address  of Environment struct */
 	unsigned long	env_valid;	/* Checksum of Environment valid? */
 	void		**jt;		/* jump table */
+	char		env_buf[32];	/* buffer for getenv() before reloc. */
 } gd_t;
 
 /*
@@ -57,7 +58,7 @@ typedef	struct	global_data {
 #define	GD_FLG_POSTFAIL	0x00008		/* Critical POST test failed	 */
 #define	GD_FLG_POSTSTOP	0x00010		/* POST seqeunce aborted	 */
 #define	GD_FLG_LOGINIT	0x00020		/* Log Buf has been initialized	 */
-#define GD_FLG_DISABLE_CONSOLE	0x00040		/* Disable console (in & out)	 */
+#define GD_FLG_DISABLE_CONSOLE	0x00040	/* Disable console (in & out)		*/
 
 #define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("k0")
 

+ 2 - 1
arch/nios2/include/asm/global_data.h

@@ -37,6 +37,7 @@ typedef	struct	global_data {
 	unsigned long	post_init_f_time; /* When post_init_f started */
 #endif
 	void		**jt;		/* Standalone app jump table */
+	char		env_buf[32];	/* buffer for getenv() before reloc. */
 } gd_t;
 
 /* flags */
@@ -46,7 +47,7 @@ typedef	struct	global_data {
 #define	GD_FLG_POSTFAIL	0x00008		/* Critical POST test failed		*/
 #define	GD_FLG_POSTSTOP	0x00010		/* POST seqeunce aborted		*/
 #define	GD_FLG_LOGINIT	0x00020		/* Log Buffer has been initialized	*/
-#define GD_FLG_DISABLE_CONSOLE	0x00040		/* Disable console (in & out)	 */
+#define GD_FLG_DISABLE_CONSOLE	0x00040	/* Disable console (in & out)		*/
 
 #define DECLARE_GLOBAL_DATA_PTR     register gd_t *gd asm ("gp")
 

+ 3 - 2
arch/powerpc/include/asm/global_data.h

@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2002
+ * (C) Copyright 2002-2010
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  * See file CREDITS for list of people who contributed to this
@@ -176,6 +176,7 @@ typedef	struct	global_data {
 	unsigned long long wdt_last;	/* trace watch-dog triggering rate */
 #endif
 	void		**jt;		/* jump table */
+	char		env_buf[32];	/* buffer for getenv() before reloc. */
 } gd_t;
 
 /*
@@ -187,7 +188,7 @@ typedef	struct	global_data {
 #define	GD_FLG_POSTFAIL	0x00008		/* Critical POST test failed		*/
 #define	GD_FLG_POSTSTOP	0x00010		/* POST seqeunce aborted		*/
 #define	GD_FLG_LOGINIT	0x00020		/* Log Buffer has been initialized	*/
-#define GD_FLG_DISABLE_CONSOLE	0x00040		/* Disable console (in & out)	 */
+#define GD_FLG_DISABLE_CONSOLE	0x00040	/* Disable console (in & out)		*/
 
 #if 1
 #define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r2")

+ 4 - 3
arch/sh/include/asm/global_data.h

@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2002
+ * (C) Copyright 2002-2010
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  * (C) Copyright 2007
@@ -38,7 +38,8 @@ typedef	struct global_data
 	unsigned long	env_addr;	/* Address  of Environment struct */
 	unsigned long	env_valid;	/* Checksum of Environment valid */
 	void		**jt;		/* Standalone app jump table */
-}gd_t;
+	char		env_buf[32];	/* buffer for getenv() before reloc. */
+} gd_t;
 
 #define	GD_FLG_RELOC	0x00001		/* Code was relocated to RAM		*/
 #define	GD_FLG_DEVINIT	0x00002		/* Devices have been initialized	*/
@@ -46,7 +47,7 @@ typedef	struct global_data
 #define	GD_FLG_POSTFAIL	0x00008		/* Critical POST test failed		*/
 #define	GD_FLG_POSTSTOP	0x00010		/* POST seqeunce aborted		*/
 #define	GD_FLG_LOGINIT	0x00020		/* Log Buffer has been initialized	*/
-#define GD_FLG_DISABLE_CONSOLE	0x00040		/* Disable console (in & out)	 */
+#define GD_FLG_DISABLE_CONSOLE	0x00040	/* Disable console (in & out)		*/
 
 #define DECLARE_GLOBAL_DATA_PTR	register gd_t *gd asm ("r13")
 

+ 4 - 3
arch/sparc/include/asm/global_data.h

@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2002
+ * (C) Copyright 2002-2010
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  * (C) Copyright 2007
@@ -70,7 +70,8 @@ typedef struct global_data {
 #ifdef CONFIG_LWMON
 	unsigned long kbd_status;
 #endif
-	void **jt;		/* jump table */
+	void	**jt;			/* jump table */
+	char	env_buf[32];		/* buffer for getenv() before reloc. */
 } gd_t;
 
 /*
@@ -82,7 +83,7 @@ typedef struct global_data {
 #define	GD_FLG_POSTFAIL	0x00008	/* Critical POST test failed		*/
 #define	GD_FLG_POSTSTOP	0x00010	/* POST seqeunce aborted		*/
 #define	GD_FLG_LOGINIT	0x00020	/* Log Buffer has been initialized	*/
-#define GD_FLG_DISABLE_CONSOLE	0x00040		/* Disable console (in & out)	 */
+#define GD_FLG_DISABLE_CONSOLE	0x00040	/* Disable console (in & out)	*/
 
 #define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("%g7")
 

+ 18 - 11
common/cmd_nvedit.c

@@ -511,24 +511,31 @@ int do_editenv(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
 char *getenv (char *name)
 {
-	int i, nxt;
+	if (gd->flags & GD_FLG_RELOC) {	/* full C runtime after reloc */
+		int i, nxt;
 
-	WATCHDOG_RESET();
+		WATCHDOG_RESET();
 
-	for (i=0; env_get_char(i) != '\0'; i=nxt+1) {
-		int val;
+		for (i=0; env_get_char(i) != '\0'; i=nxt+1) {
+			int val;
 
-		for (nxt=i; env_get_char(nxt) != '\0'; ++nxt) {
-			if (nxt >= CONFIG_ENV_SIZE) {
-				return (NULL);
+			for (nxt=i; env_get_char(nxt) != '\0'; ++nxt) {
+				if (nxt >= CONFIG_ENV_SIZE) {
+					return (NULL);
+				}
 			}
+			if ((val=envmatch((uchar *)name, i)) < 0)
+				continue;
+			return ((char *)env_get_addr(val));
 		}
-		if ((val=envmatch((uchar *)name, i)) < 0)
-			continue;
-		return ((char *)env_get_addr(val));
+
+		return (NULL);
 	}
 
-	return (NULL);
+	/* restricted C runtime before reloc */
+
+	return ((getenv_f(name,gd->env_buf,sizeof(gd->env_buf)) > 0) ?
+		gd->env_buf : NULL);
 }
 
 int getenv_f(char *name, char *buf, unsigned len)