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 (mpl@broadcom.com) 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 as 24 * 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. Neither the "Broadcom 28 * Corporation" name nor any trademark or logo of Broadcom 29 * Corporation may be used to endorse or promote products 30 * derived from this software without the prior written 31 * permission of Broadcom Corporation. 32 * 33 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 34 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 35 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 36 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 37 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 38 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 39 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 40 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 41 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 43 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 44 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 45 * THE POSSIBILITY OF SUCH DAMAGE. 46 ********************************************************************* */ 47 48#include "lib_types.h" 49#include "lib_string.h" 50#include "lib_queue.h" 51#include "lib_malloc.h" 52#include "lib_printf.h" 53 54#include "bsp_config.h" 55#include "cfe_loader.h" 56#include "cfe_autoboot.h" 57#include "cfe_iocb.h" 58#include "cfe_devfuncs.h" 59#include "cfe_fileops.h" 60#include "cfe_error.h" 61 62#include "net_ebuf.h" 63#include "net_ether.h" 64#include "net_api.h" 65 66#include "ui_command.h" 67 68#include "url.h" 69 70static long getaddr(char *str) 71{ 72 /* 73 * hold on to your lunch, this is really, really bad! 74 * Make 64-bit addresses expressed as 8-digit numbers 75 * sign extend automagically. Saves typing, but is very 76 * gross. Not very portable, either. 77 */ 78 int longaddr = 0; 79 long newaddr; 80 81 longaddr = strlen(str); 82 if (memcmp(str,"0x",2) == 0) longaddr -= 2; 83 longaddr = (longaddr > 8) ? 1 : 0; 84 85 if (longaddr) newaddr = (long) xtoq(str); 86 else newaddr = (long) xtoi(str); 87 88 return newaddr; 89} 90 91static int process_oldstyle(char *str, 92 ui_cmdline_t *cmd, 93 cfe_loadargs_t *la) 94{ 95 char *file; 96 char *devname; 97 char *filesys = NULL; 98 char *loader = la->la_loader; 99 char *x; 100 int info; 101 char *colon; 102 103 colon = strchr(str,':'); 104 105 if (!colon) { 106 return CFE_ERR_DEVNOTFOUND; 107 } 108 109 devname = str; /* will be used to check protocol later */ 110 *colon = '\0'; 111 file = colon + 1; /* Ugly, we might put the colon back! */ 112 113 /* 114 * Try to determine the load protocol ("filesystem") 115 * first by using the command line, and 116 * if not that try to figure it out automagically 117 */ 118 119 if (cmd_sw_isset(cmd,"-fatfs")) filesys = "fat"; 120 if (cmd_sw_isset(cmd,"-tftp")) filesys = "tftp"; 121 if (cmd_sw_isset(cmd,"-rawfs")) filesys = "raw"; 122#if CFG_TCP && CFG_HTTPFS 123 if (cmd_sw_isset(cmd,"-http")) filesys = "http"; 124#endif 125 if (cmd_sw_value(cmd,"-fs",&x)) filesys = x; 126 127 /* 128 * Automagic configuration 129 */ 130 131 /* 132 * Determine the device type from the "host" name. If we look 133 * up the host name and it appears to be an invalid CFE device 134 * name, then it's probably a TFTP host name. 135 * 136 * This is where we guess based on the device type what 137 * sort of load method we're going to use. 138 */ 139 140 info = devname ? cfe_getdevinfo(devname) : -1; 141 if (info >= 0) { 142 switch (info & CFE_DEV_MASK) { 143 case CFE_DEV_NETWORK: 144 if (!filesys) filesys = "tftp"; 145 if (!loader) loader = "raw"; 146 break; 147 case CFE_DEV_DISK: 148 if (!filesys) filesys = "raw"; 149 if (!loader) loader = "raw"; 150 break; 151 case CFE_DEV_FLASH: 152 if (!filesys) filesys = "raw"; 153 if (!loader) loader = "raw"; 154 break; 155 case CFE_DEV_SERIAL: 156 if (!filesys) filesys = "raw"; 157 if (!loader) loader = "srec"; 158 break; 159 default: 160 break; 161 } 162 la->la_device = devname; 163 la->la_filename = file; 164 } 165 else { 166 /* 167 * It's probably a network boot. Default to TFTP 168 * if not overridden 169 */ 170#if CFG_NETWORK 171 la->la_device = (char *) net_getparam(NET_DEVNAME); 172#else 173 la->la_device = NULL; 174#endif 175 *colon = ':'; /* put the colon back */ 176 la->la_filename = devname; 177 if (!filesys) filesys = "tftp"; 178 if (!loader) loader = "raw"; 179 } 180 181 /* 182 * Remember our file system and loader. 183 */ 184 185 la->la_filesys = filesys; 186 la->la_loader = loader; 187 188 return 0; 189} 190 191 192#if CFG_URLS 193static int process_url(char *str, 194 ui_cmdline_t *cmd, 195 cfe_loadargs_t *la) 196{ 197 char *p; 198 char *protocol; 199 int idx,len; 200 int network = 0; 201 const fileio_dispatch_t *fdisp; 202 203 /* 204 * All URLs have the string "://" in them somewhere 205 * If that's not there, try the old syntax. 206 */ 207 208 len = strlen(str); 209 p = str; 210 211 for (idx = 0; idx < len-3; idx++) { 212 if (memcmp(p,"://",3) == 0) break; 213 p++; 214 } 215 216 if (idx == (len-3)) { 217 return process_oldstyle(str,cmd,la); 218 } 219 220 /* 221 * Break the string apart into protocol, host, file 222 */ 223 224 protocol = str; 225 *p = '\0'; 226 p += 3; 227 228 /* 229 * Determine if this is a network loader. If that is true, 230 * the meaning of the "device" field is different. Ugh. 231 */ 232 233 fdisp = cfe_findfilesys(protocol); 234 if (fdisp && (fdisp->loadflags & FSYS_TYPE_NETWORK)) network = 1; 235 236 /* 237 * Depending on the protocol we parse the file name one of two ways: 238 * 239 * protocol://hostname/filename 240 * 241 * For network devices: 242 * 243 * the "device" is the current Ethernet device. 244 * The filename is the //hostname/filename from the URL. 245 * 246 * For non-network devices: 247 * 248 * The "device" is the CFE device name from the URL 'hostname' field 249 * The filename is from the URL filename field. 250 */ 251 252 la->la_filesys = protocol; 253 254 if (network) { 255#if CFG_NETWORK 256 la->la_device = (char *) net_getparam(NET_DEVNAME); 257#else 258 la->la_device = NULL; 259#endif 260 la->la_filename = p; 261 } 262 else { 263 la->la_device = p; 264 p = strchr(p,'/'); 265 if (p) { 266 *p++ = '\0'; 267 la->la_filename = p; 268 } 269 else { 270 la->la_filename = NULL; 271 } 272 } 273 274 if (!la->la_loader) la->la_loader = "raw"; 275 276 return 0; 277} 278#endif 279 280 281 282int ui_process_url(char *url,ui_cmdline_t *cmd,cfe_loadargs_t *la) 283{ 284 int res; 285 char *x; 286 287 /* 288 * Skip leading whitespace 289 */ 290 291 while (*url && ((*url == ' ') || (*url == '\t'))) url++; 292 293 /* 294 * Process command-line switches to determine the loader stack 295 */ 296 297 la->la_loader = NULL; 298 if (cmd_sw_isset(cmd,"-elf")) la->la_loader = "elf"; 299 if (cmd_sw_isset(cmd,"-srec")) la->la_loader = "srec"; 300 if (cmd_sw_isset(cmd,"-raw")) la->la_loader = "raw"; 301 if (cmd_sw_value(cmd,"-loader",&x)) la->la_loader = x; 302 303#if CFG_ZLIB || CFG_LZMA 304 if (cmd_sw_isset(cmd,"-z")) { 305 la->la_flags |= LOADFLG_COMPRESSED; 306 } 307#endif 308 309 /* 310 * Parse the file name into its pieces. 311 */ 312 313#if CFG_URLS 314 res = process_url(url,cmd,la); 315 if (res < 0) return res; 316#else 317 res = process_oldstyle(url,cmd,la); 318 if (res < 0) return res; 319#endif 320 321 322 /* 323 * This is used only by "boot" and "load" - to avoid this code 324 * don't include these switches in the command table. 325 */ 326 327 if (cmd_sw_value(cmd,"-max",&x)) { 328 la->la_maxsize = atoi(x); 329 } 330 331 if (cmd_sw_value(cmd,"-addr",&x)) { 332 la->la_address = getaddr(x); 333 la->la_flags |= LOADFLG_SPECADDR; 334 } 335 336 if (cmd_sw_isset(cmd,"-noclose")) { 337 la->la_flags |= LOADFLG_NOCLOSE; 338 } 339 340 341 return 0; 342} 343