* Patch by Hans-Joerg Frieden, 06 Dec 2002
[platform/kernel/u-boot.git] / common / env_common.c
1 /*
2  * (C) Copyright 2000-2002
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
6  * Andreas Heppel <aheppel@sysgo.de>
7
8  * See file CREDITS for list of people who contributed to this
9  * project.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License as
13  * published by the Free Software Foundation; either version 2 of
14  * the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24  * MA 02111-1307 USA
25  */
26
27 #include <common.h>
28 #include <command.h>
29 #include <environment.h>
30 #include <cmd_nvedit.h>
31 #include <linux/stddef.h>
32 #include <malloc.h>
33
34 #ifdef CONFIG_SHOW_BOOT_PROGRESS
35 # include <status_led.h>
36 # define SHOW_BOOT_PROGRESS(arg)        show_boot_progress(arg)
37 #else
38 # define SHOW_BOOT_PROGRESS(arg)
39 #endif
40
41 #ifdef CONFIG_AMIGAONEG3SE
42         extern void enable_nvram(void);
43         extern void disable_nvram(void);
44 #endif
45
46 #undef DEBUG_ENV
47 #ifdef DEBUG_ENV
48 #define DEBUGF(fmt,args...) printf(fmt ,##args)
49 #else
50 #define DEBUGF(fmt,args...)
51 #endif
52
53 extern env_t *env_ptr;
54
55 extern void env_relocate_spec (void);
56 extern uchar env_get_char_spec(int);
57
58 static uchar env_get_char_init (int index);
59 uchar (*env_get_char)(int) = env_get_char_init;
60
61 /************************************************************************
62  * Default settings to be used when no valid environment is found
63  */
64 #define XMK_STR(x)      #x
65 #define MK_STR(x)       XMK_STR(x)
66
67 uchar default_environment[] = {
68 #ifdef  CONFIG_BOOTARGS
69         "bootargs="     CONFIG_BOOTARGS                 "\0"
70 #endif
71 #ifdef  CONFIG_BOOTCOMMAND
72         "bootcmd="      CONFIG_BOOTCOMMAND              "\0"
73 #endif
74 #ifdef  CONFIG_RAMBOOTCOMMAND
75         "ramboot="      CONFIG_RAMBOOTCOMMAND           "\0"
76 #endif
77 #ifdef  CONFIG_NFSBOOTCOMMAND
78         "nfsboot="      CONFIG_NFSBOOTCOMMAND           "\0"
79 #endif
80 #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
81         "bootdelay="    MK_STR(CONFIG_BOOTDELAY)        "\0"
82 #endif
83 #if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)
84         "baudrate="     MK_STR(CONFIG_BAUDRATE)         "\0"
85 #endif
86 #ifdef  CONFIG_LOADS_ECHO
87         "loads_echo="   MK_STR(CONFIG_LOADS_ECHO)       "\0"
88 #endif
89 #ifdef  CONFIG_ETHADDR
90         "ethaddr="      MK_STR(CONFIG_ETHADDR)          "\0"
91 #endif
92 #ifdef  CONFIG_ETH1ADDR
93         "eth1addr="     MK_STR(CONFIG_ETH1ADDR)         "\0"
94 #endif
95 #ifdef  CONFIG_ETH2ADDR
96         "eth2addr="     MK_STR(CONFIG_ETH2ADDR)         "\0"
97 #endif
98 #ifdef  CONFIG_IPADDR
99         "ipaddr="       MK_STR(CONFIG_IPADDR)           "\0"
100 #endif
101 #ifdef  CONFIG_SERVERIP
102         "serverip="     MK_STR(CONFIG_SERVERIP)         "\0"
103 #endif
104 #ifdef  CFG_AUTOLOAD
105         "autoload="     CFG_AUTOLOAD                    "\0"
106 #endif
107 #ifdef  CONFIG_PREBOOT
108         "preboot="      CONFIG_PREBOOT                  "\0"
109 #endif
110 #ifdef  CONFIG_ROOTPATH
111         "rootpath="     MK_STR(CONFIG_ROOTPATH)         "\0"
112 #endif
113 #ifdef  CONFIG_GATEWAYIP
114         "gatewayip="    MK_STR(CONFIG_GATEWAYIP)        "\0"
115 #endif
116 #ifdef  CONFIG_NETMASK
117         "netmask="      MK_STR(CONFIG_NETMASK)          "\0"
118 #endif
119 #ifdef  CONFIG_HOSTNAME
120         "hostname="     MK_STR(CONFIG_HOSTNAME)         "\0"
121 #endif
122 #ifdef  CONFIG_BOOTFILE
123         "bootfile="     MK_STR(CONFIG_BOOTFILE)         "\0"
124 #endif
125 #ifdef  CONFIG_LOADADDR
126         "loadaddr="     MK_STR(CONFIG_LOADADDR)         "\0"
127 #endif
128 #ifdef  CONFIG_CLOCKS_IN_MHZ
129         "clocks_in_mhz=1\0"
130 #endif
131 #ifdef  CONFIG_EXTRA_ENV_SETTINGS
132         CONFIG_EXTRA_ENV_SETTINGS
133 #endif
134         "\0"
135 };
136
137
138 void env_crc_update (void)
139 {
140         env_ptr->crc = crc32(0, env_ptr->data, ENV_SIZE);
141 }
142
143 static uchar env_get_char_init (int index)
144 {
145         DECLARE_GLOBAL_DATA_PTR;
146         uchar c;
147
148         /* if crc was bad, use the default environment */
149         if (gd->env_valid)
150         {
151                 c = env_get_char_spec(index);
152         } else {
153                 c = default_environment[index];
154         }
155
156         return (c);
157 }
158
159 #ifdef CONFIG_AMIGAONEG3SE
160 uchar env_get_char_memory (int index)
161 {
162         DECLARE_GLOBAL_DATA_PTR;
163         uchar retval;
164         enable_nvram();
165         if (gd->env_valid) {
166                 retval = ( *((uchar *)(gd->env_addr + index)) );
167         } else {
168                 retval = ( default_environment[index] );
169         }
170         disable_nvram();
171         return retval;
172 }
173 #else
174 uchar env_get_char_memory (int index)
175 {
176         DECLARE_GLOBAL_DATA_PTR;
177
178         if (gd->env_valid) {
179                 return ( *((uchar *)(gd->env_addr + index)) );
180         } else {
181                 return ( default_environment[index] );
182         }
183 }
184 #endif
185
186 uchar *env_get_addr (int index)
187 {
188         DECLARE_GLOBAL_DATA_PTR;
189
190         if (gd->env_valid) {
191                 return ( ((uchar *)(gd->env_addr + index)) );
192         } else {
193                 return (&default_environment[index]);
194         }
195 }
196
197 void env_relocate (void)
198 {
199         DECLARE_GLOBAL_DATA_PTR;
200
201         DEBUGF ("%s[%d] offset = 0x%lx\n", __FUNCTION__,__LINE__,
202                 gd->reloc_off);
203
204 #ifdef CONFIG_AMIGAONEG3SE
205         enable_nvram();
206 #endif
207
208 #ifdef ENV_IS_EMBEDDED
209         /*
210          * The environment buffer is embedded with the text segment,
211          * just relocate the environment pointer
212          */
213         env_ptr = (env_t *)((ulong)env_ptr + gd->reloc_off);
214         DEBUGF ("%s[%d] embedded ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
215 #else
216         /*
217          * We must allocate a buffer for the environment
218          */
219         env_ptr = (env_t *)malloc (CFG_ENV_SIZE);
220         DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
221 #endif
222
223         /*
224          * After relocation to RAM, we can always use the "memory" functions
225          */
226         env_get_char = env_get_char_memory;
227
228         if (gd->env_valid == 0) {
229 #if defined(CONFIG_GTH) || defined(CFG_ENV_IS_NOWHERE)  /* Environment not changable */
230                 puts ("Using default environment\n\n");
231 #else
232                 puts ("*** Warning - bad CRC, using default environment\n\n");
233                 SHOW_BOOT_PROGRESS (-1);
234 #endif
235
236                 if (sizeof(default_environment) > ENV_SIZE)
237                 {
238                         puts ("*** Error - default environment is too large\n\n");
239                         return;
240                 }
241
242                 memset (env_ptr, 0, sizeof(env_t));
243                 memcpy (env_ptr->data,
244                         default_environment,
245                         sizeof(default_environment));
246 #ifdef CFG_REDUNDAND_ENVIRONMENT
247                 env_ptr->flags = 0xFF;
248 #endif
249                 env_crc_update ();
250                 gd->env_valid = 1;
251         }
252         else {
253                 env_relocate_spec ();
254         }
255         gd->env_addr = (ulong)&(env_ptr->data);
256
257 #ifdef CONFIG_AMIGAONEG3SE
258         disable_nvram();
259 #endif
260 }