* Patch by Thomas Frieden, 13 Nov 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 uchar env_get_char_memory (int index)
160 {
161         DECLARE_GLOBAL_DATA_PTR;
162
163         if (gd->env_valid) {
164                 return ( *((uchar *)(gd->env_addr + index)) );
165         } else {
166                 return ( default_environment[index] );
167         }
168 }
169
170 uchar *env_get_addr (int index)
171 {
172         DECLARE_GLOBAL_DATA_PTR;
173
174         if (gd->env_valid) {
175                 return ( ((uchar *)(gd->env_addr + index)) );
176         } else {
177                 return (&default_environment[index]);
178         }
179 }
180
181 void env_relocate (void)
182 {
183         DECLARE_GLOBAL_DATA_PTR;
184
185         DEBUGF ("%s[%d] offset = 0x%lx\n", __FUNCTION__,__LINE__,
186                 gd->reloc_off);
187
188 #ifdef CONFIG_AMIGAONEG3SE
189         enable_nvram();
190 #endif
191
192 #ifdef ENV_IS_EMBEDDED
193         /*
194          * The environment buffer is embedded with the text segment,
195          * just relocate the environment pointer
196          */
197         env_ptr = (env_t *)((ulong)env_ptr + gd->reloc_off);
198         DEBUGF ("%s[%d] embedded ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
199 #else
200         /*
201          * We must allocate a buffer for the environment
202          */
203         env_ptr = (env_t *)malloc (CFG_ENV_SIZE);
204         DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
205 #endif
206
207         /*
208          * After relocation to RAM, we can always use the "memory" functions
209          */
210         env_get_char = env_get_char_memory;
211
212         if (gd->env_valid == 0) {
213 #if defined(CONFIG_GTH) || defined(CFG_ENV_IS_NOWHERE)  /* Environment not changable */
214                 puts ("Using default environment\n\n");
215 #else
216                 puts ("*** Warning - bad CRC, using default environment\n\n");
217                 SHOW_BOOT_PROGRESS (-1);
218 #endif
219
220                 if (sizeof(default_environment) > ENV_SIZE)
221                 {
222                         puts ("*** Error - default environment is too large\n\n");
223                         return;
224                 }
225
226                 memset (env_ptr, 0, sizeof(env_t));
227                 memcpy (env_ptr->data,
228                         default_environment,
229                         sizeof(default_environment));
230 #ifdef CFG_REDUNDAND_ENVIRONMENT
231                 env_ptr->flags = 0xFF;
232 #endif
233                 env_crc_update ();
234                 gd->env_valid = 1;
235         }
236         else {
237                 env_relocate_spec ();
238         }
239         gd->env_addr = (ulong)&(env_ptr->data);
240
241 #ifdef CONFIG_AMIGAONEG3SE
242         disable_nvram();
243 #endif
244 }