1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * Program and file loading URLs File: url.c 5 * 6 * Functions to process URLs for loading software. 7 * 8 * Author: Mitch Lichtenberg 9 * 10 ********************************************************************* 11 * 12 * Copyright 2000,2001 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 "cfe_loader.h" 50#include "cfe_autoboot.h" 51#include "cfe_fileops.h" 52 53#include "net_ebuf.h" 54#include "net_ether.h" 55#include "net_api.h" 56 57#include "ui_command.h" 58 59#include "url.h" 60 61static long getaddr(char *str) 62{ 63 /* 64 * hold on to your lunch, this is really, really bad! 65 * Make 64-bit addresses expressed as 8-digit numbers 66 * sign extend automagically. Saves typing, but is very 67 * gross. Not very portable, either. 68 */ 69 int longaddr = 0; 70 long newaddr; 71 72 longaddr = strlen(str); 73 if (memcmp(str,"0x",2) == 0) longaddr -= 2; 74 longaddr = (longaddr > 8) ? 1 : 0; 75 76 if (longaddr) newaddr = (long) xtoq(str); 77 else newaddr = (long) xtoi(str); 78 79 return newaddr; 80} 81 82static int process_oldstyle(char *str, 83 ui_cmdline_t *cmd, 84 cfe_loadargs_t *la) 85{ 86 char *file; 87 char *devname; 88 char *filesys = NULL; 89 char *loader = la->la_loader; 90 char *x; 91 int info; 92 char *colon; 93 94 colon = strchr(str,':'); 95 96 if (!colon) { 97 return CFE_ERR_DEVNOTFOUND; 98 } 99 100 devname = str; /* will be used to check protocol later */ 101 *colon = '\0'; 102 file = colon + 1; /* Ugly, we might put the colon back! */ 103 104 /* 105 * Try to determine the load protocol ("filesystem") 106 * first by using the command line, and 107 * if not that try to figure it out automagically 108 */ 109 110 if (cmd_sw_isset(cmd,"-fatfs")) filesys = "fat"; 111 if (cmd_sw_isset(cmd,"-tftp")) filesys = "tftp"; 112 if (cmd_sw_isset(cmd,"-rawfs")) filesys = "raw"; 113#if (CFG_TCP) && (CFG_HTTPFS) 114 if (cmd_sw_isset(cmd,"-http")) filesys = "http"; 115#endif 116 if (cmd_sw_value(cmd,"-fs",&x)) filesys = x; 117 118 /* 119 * Automagic configuration 120 */ 121 122 /* 123 * Determine the device type from the "host" name. If we look 124 * up the host name and it appears to be an invalid CFE device 125 * name, then it's probably a TFTP host name. 126 * 127 * This is where we guess based on the device type what 128 * sort of load method we're going to use. 129 */ 130 131 info = devname ? cfe_getdevinfo(devname) : -1; 132 if (info >= 0) { 133 switch (info & CFE_DEV_MASK) { 134 case CFE_DEV_NETWORK: 135 if (!filesys) filesys = "tftp"; 136 if (!loader) loader = "raw"; 137 break; 138 case CFE_DEV_DISK: 139 if (!filesys) filesys = "raw"; 140 if (!loader) loader = "raw"; 141 break; 142 case CFE_DEV_FLASH: 143 if (!filesys) filesys = "raw"; 144 if (!loader) loader = "raw"; 145 break; 146 case CFE_DEV_SERIAL: 147 if (!filesys) filesys = "raw"; 148 if (!loader) loader = "srec"; 149 break; 150 default: 151 break; 152 } 153 la->la_device = devname; 154 la->la_filename = file; 155 } 156 else { 157 /* 158 * It's probably a network boot. Default to TFTP 159 * if not overridden 160 */ 161#if CFG_NETWORK 162 la->la_device = (char *) net_getparam(NET_DEVNAME); 163#else 164 la->la_device = NULL; 165#endif 166 *colon = ':'; /* put the colon back */ 167 la->la_filename = devname; 168 if (!filesys) filesys = "tftp"; 169 if (!loader) loader = "raw"; 170 } 171 172 /* 173 * Remember our file system and loader. 174 */ 175 176 la->la_filesys = filesys; 177 la->la_loader = loader; 178 179 return 0; 180} 181 182 183#if CFG_URLS 184static int process_url(char *str, 185 ui_cmdline_t *cmd, 186 cfe_loadargs_t *la) 187{ 188 char *p; 189 char *protocol; 190 int idx,len; 191 int network = 0; 192 const fileio_dispatch_t *fdisp; 193 194 /* 195 * All URLs have the string "://" in them somewhere 196 * If that's not there, try the old syntax. 197 */ 198 199 len = strlen(str); 200 p = str; 201 202 for (idx = 0; idx < len-3; idx++) { 203 if (memcmp(p,"://",3) == 0) break; 204 p++; 205 } 206 207 if (idx == (len-3)) { 208 return process_oldstyle(str,cmd,la); 209 } 210 211 /* 212 * Break the string apart into protocol, host, file 213 */ 214 215 protocol = str; 216 *p = '\0'; 217 p += 3; 218 219 /* 220 * Determine if this is a network loader. If that is true, 221 * the meaning of the "device" field is different. Ugh. 222 */ 223 224 fdisp = cfe_findfilesys(protocol); 225 if (fdisp && (fdisp->loadflags & FSYS_TYPE_NETWORK)) network = 1; 226 227 /* 228 * Depending on the protocol we parse the file name one of two ways: 229 * 230 * protocol://hostname/filename 231 * 232 * For network devices: 233 * 234 * the "device" is the current Ethernet device. 235 * The filename is the //hostname/filename from the URL. 236 * 237 * For non-network devices: 238 * 239 * The "device" is the CFE device name from the URL 'hostname' field 240 * The filename is from the URL filename field. 241 */ 242 243 la->la_filesys = protocol; 244 245 if (network) { 246#if CFG_NETWORK 247 la->la_device = (char *) net_getparam(NET_DEVNAME); 248#else 249 la->la_device = NULL; 250#endif 251 la->la_filename = p; 252 } 253 else { 254 la->la_device = p; 255 p = strchr(p,'/'); 256 if (p) { 257 *p++ = '\0'; 258 la->la_filename = p; 259 } 260 else { 261 la->la_filename = NULL; 262 } 263 } 264 265 if (!la->la_loader) la->la_loader = "raw"; 266 267 return 0; 268} 269#endif 270 271 272 273int ui_process_url(char *url,ui_cmdline_t *cmd,cfe_loadargs_t *la) 274{ 275 int res; 276 char *x; 277 278 /* 279 * Skip leading whitespace 280 */ 281 282 while (*url && ((*url == ' ') || (*url == '\t'))) url++; 283 284 /* 285 * Process command-line switches to determine the loader stack 286 */ 287 288 la->la_loader = NULL; 289 if (cmd_sw_isset(cmd,"-elf")) la->la_loader = "elf"; 290 if (cmd_sw_isset(cmd,"-srec")) la->la_loader = "srec"; 291 if (cmd_sw_isset(cmd,"-raw")) la->la_loader = "raw"; 292 if (cmd_sw_isset(cmd,"-uboot")) la->la_loader = "uboot"; 293 if (cmd_sw_value(cmd,"-loader",&x)) la->la_loader = x; 294 295#if CFG_ZLIB 296 if (cmd_sw_isset(cmd,"-z")) { 297 la->la_flags |= LOADFLG_COMPRESSED; 298 } 299#endif 300 301 /* 302 * Parse the file name into its pieces. 303 */ 304 305#if CFG_URLS 306 res = process_url(url,cmd,la); 307 if (res < 0) return res; 308#else 309 res = process_oldstyle(url,cmd,la); 310 if (res < 0) return res; 311#endif 312 313 314 /* 315 * This is used only by "boot" and "load" - to avoid this code 316 * don't include these switches in the command table. 317 */ 318 319 if (cmd_sw_value(cmd,"-max",&x)) { 320 la->la_maxsize = atoi(x); 321 } 322 323 if (cmd_sw_value(cmd,"-addr",&x)) { 324 la->la_address = getaddr(x); 325 la->la_flags |= LOADFLG_SPECADDR; 326 } 327 328 if (cmd_sw_isset(cmd,"-noclose")) { 329 la->la_flags |= LOADFLG_NOCLOSE; 330 } 331 332#if 0 333 printf("--- Loader parameters:\n"); 334 printf(" Filename = %s\n",la->la_filename); 335 printf(" Filesys = %s\n",la->la_filesys); 336 printf(" Device = %s\n",la->la_device); 337 printf(" Options = %s\n",la->la_options); 338 printf(" Loader = %s\n",la->la_loader); 339 printf(" Flags = %08X\n",la->la_flags); 340 printf(" address = %08X\n",la->la_address); 341 printf(" maxsize = %08X\n",la->la_maxsize); 342 printf(" entrypt = %08X\n",la->la_entrypt); 343#endif 344 345 return 0; 346} 347 348 349 350