1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  OS bootstrap				File: cfe_boot.c
5    *
6    *  This module handles OS bootstrap stuff
7    *
8    *  Author:  Mitch Lichtenberg
9    *
10    *********************************************************************
11    *
12    *  Copyright 2000,2001,2002,2003
13    *  Broadcom Corporation. All rights reserved.
14    *
15    *  This software is furnished under license and may be used and
16    *  copied only in accordance with the following terms and
17    *  conditions.  Subject to these conditions, you may download,
18    *  copy, install, use, modify and distribute modified or unmodified
19    *  copies of this software in source and/or binary form.  No title
20    *  or ownership is transferred hereby.
21    *
22    *  1) Any source code used, modified or distributed must reproduce
23    *     and retain this copyright notice and list of conditions
24    *     as they appear in the source file.
25    *
26    *  2) No right is granted to use any trade name, trademark, or
27    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
28    *     name may not be used to endorse or promote products derived
29    *     from this software without the prior written permission of
30    *     Broadcom Corporation.
31    *
32    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
33    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
34    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
35    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
36    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
37    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
38    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
40    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
42    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
43    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
44    *     THE POSSIBILITY OF SUCH DAMAGE.
45    ********************************************************************* */
46
47#include "cfe.h"
48
49#include "env_subr.h"
50
51#include "net_ebuf.h"
52#include "net_ether.h"
53
54#include "net_api.h"
55#include "cfe_fileops.h"
56#include "cfe_bootblock.h"
57#include "cfe_boot.h"
58
59#include "cfe_loader.h"
60
61#if CFG_UI
62extern int ui_docommands(char *buf);
63#endif
64
65/*  *********************************************************************
66    *  data
67    ********************************************************************* */
68
69const char *bootvar_device = "BOOT_DEVICE";
70const char *bootvar_file   = "BOOT_FILE";
71const char *bootvar_flags  = "BOOT_FLAGS";
72
73cfe_loadargs_t cfe_loadargs;
74
75/*  *********************************************************************
76    *  splitpath(path,devname,filename)
77    *
78    *  Split a path name (a boot path, in the form device:filename)
79    *  into its parts
80    *
81    *  Input parameters:
82    *  	   path - pointer to path string
83    *  	   devname - receives pointer to device name
84    *  	   filename - receives pointer to file name
85    *
86    *  Return value:
87    *  	   nothing
88    ********************************************************************* */
89
90void splitpath(char *path,char **devname,char **filename)
91{
92    char *x;
93
94    *devname = NULL;
95    *filename = NULL;
96
97    x = strchr(path,':');
98
99    if (!x) {
100	*devname = NULL;	/* path consists of device name */
101	*filename = path;
102	}
103    else {
104	*x++ = '\0';		/* have both device and file name */
105	*filename = x;
106	*devname = path;
107	}
108}
109
110
111/*  *********************************************************************
112    *  cfe_go(la)
113    *
114    *  Starts a previously loaded program.  cfe_loadargs.la_entrypt
115    *  must be set to the entry point of the program to be started
116    *
117    *  Input parameters:
118    *  	   la - loader args
119    *
120    *  Return value:
121    *  	   does not return
122    ********************************************************************* */
123
124void cfe_go(cfe_loadargs_t *la)
125{
126#if CFG_NETWORK
127    if (!(la->la_flags & LOADFLG_NOCLOSE)) {
128	if (net_getparam(NET_DEVNAME)) {
129	    xprintf("Closing network.\n");
130	    net_uninit();
131	    }
132	}
133#endif
134
135    xprintf("Starting program at 0x%p\n",la->la_entrypt);
136
137    /* Let console flush buffers */
138    cfe_sleep(CFE_HZ/8);
139    xprintf("\n");
140    cfe_sleep(CFE_HZ/8);
141
142    cfe_start(la->la_entrypt);
143}
144
145
146/*  *********************************************************************
147    *  cfe_boot(la)
148    *
149    *  Bootstrap the system.
150    *
151    *  Input parameters:
152    *  	   la - loader arguments
153    *
154    *  Return value:
155    *  	   error, or does not return
156    ********************************************************************* */
157int cfe_boot(char *ldrname,cfe_loadargs_t *la)
158{
159    int res;
160
161    la->la_entrypt = 0;
162
163    if (la->la_flags & LOADFLG_NOISY) {
164	xprintf("Loading: ");
165	}
166
167    res = cfe_load_program(ldrname,la);
168
169    if (res < 0) {
170	if (la->la_flags & LOADFLG_NOISY) {
171	    xprintf("Failed.\n");
172	    }
173	return res;
174	}
175
176    /*
177     * Special case: If loading a batch file, just do the commands here
178     * and return.  For batch files we don't want to set up the
179     * environment variables.
180     */
181
182    if (la->la_flags & LOADFLG_BATCH) {
183#if CFG_UI
184	ui_docommands((char *) HSADDR2PTR(la->la_entrypt));
185#endif
186	return 0;
187	}
188
189    /*
190     * Otherwise set up for running a real program.
191     */
192
193    if (la->la_flags & LOADFLG_NOISY) {
194	xprintf("Entry at 0x%p\n",la->la_entrypt);
195	}
196
197    /*
198     * Set up the environment variables for the bootstrap
199     */
200
201    if (la->la_device) {
202	env_setenv(bootvar_device,la->la_device,ENV_FLG_BUILTIN);
203	}
204    else {
205	env_delenv(bootvar_device);
206	}
207
208    if (la->la_filename) {
209	env_setenv(bootvar_file,la->la_filename,ENV_FLG_BUILTIN);
210	}
211    else {
212	env_delenv(bootvar_file);
213	}
214
215    if (la->la_options) {
216	env_setenv(bootvar_flags,la->la_options,ENV_FLG_BUILTIN);
217	}
218    else {
219	env_delenv(bootvar_flags);
220	}
221
222    /*
223     * Banzai!  Run the program.
224     */
225
226    if (la->la_flags & LOADFLG_EXECUTE) {
227	cfe_go(la);
228	}
229
230    return 0;
231}
232
233