1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * Test commands File: cfe_tests.c 5 * 6 * A temporary sandbox for misc test routines and commands. 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 accoddance 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 49#include "lib_types.h" 50#include "lib_string.h" 51#include "lib_queue.h" 52#include "lib_malloc.h" 53#include "lib_printf.h" 54#include "cfe.h" 55#include "cfe_iocb.h" 56#include "cfe_devfuncs.h" 57#include "cfe_error.h" 58#include "cfe_fileops.h" 59#include "cfe_loader.h" 60#include "ui_command.h" 61#include "bsp_config.h" 62 63#include <typedefs.h> 64#include <osl.h> 65#include <bcmutils.h> 66#include <sbutils.h> 67#include <sbconfig.h> 68#include <sbchipc.h> 69#include <sbmemc.h> 70#include <bcmendian.h> 71#include <bcmnvram.h> 72#include <hndcpu.h> 73#include <trxhdr.h> 74#include "addrspace.h" 75#include "initdata.h" 76 77#include "bsp_priv.h" 78 79/* Additional BSP UI */ 80#if CFG_ET 81extern int ui_cmd_et(ui_cmdline_t *cmd, int argc, char *argv[]); 82#endif 83 84static int 85ui_cmd_reboot(ui_cmdline_t *cmd, int argc, char *argv[]) 86{ 87 hnd_cpu_reset(sbh); 88 return 0; 89} 90 91static int 92ui_cmd_nvram(ui_cmdline_t *cmd, int argc, char *argv[]) 93{ 94 char *command, *name, *value, *buf; 95 size_t size; 96 int ret; 97 98 if (!(command = cmd_getarg(cmd, 0))) 99 return CFE_ERR_INV_PARAM; 100 101 if (!strcmp(command, "get")) { 102 if ((name = cmd_getarg(cmd, 1))) 103 if ((value = nvram_get(name))) 104 printf("%s\n", value); 105 } 106 else if (!strcmp(command, "set")){ 107 if ((name = cmd_getarg(cmd, 1))) { 108 if ((value = strchr(name, '='))) 109 *value++ = '\0'; 110 else if ((value = cmd_getarg(cmd, 2))) { 111 if (*value == '=') 112 value = cmd_getarg(cmd, 3); 113 } 114 if (value) 115 nvram_set(name, value); 116 } 117 } 118 else if (!strcmp(command, "unset")) { 119 if ((name = cmd_getarg(cmd, 1))) 120 nvram_unset(name); 121 } 122 else if (!strcmp(command, "commit")) { 123 nvram_commit(); 124 } 125 else if (!strcmp(command, "erase")) { 126 if ((ret = cfe_open("flash0.nvram")) < 0) 127 return ret; 128 if (!(buf = KMALLOC(NVRAM_SPACE, 0))) 129 return CFE_ERR_NOMEM; 130 memset(buf, 0xff, NVRAM_SPACE); 131 cfe_writeblk(ret, 0, buf, NVRAM_SPACE); 132 cfe_close(ret); 133 KFREE(buf); 134 } 135 else if (!strcmp(command, "show") || !strcmp(command, "getall")) { 136 if (!(buf = KMALLOC(NVRAM_SPACE, 0))) 137 return CFE_ERR_NOMEM; 138 nvram_getall(buf, NVRAM_SPACE); 139 for (name = buf; *name; name += strlen(name) + 1) 140 printf("%s\n", name); 141 size = sizeof(struct nvram_header) + (name - buf); 142 printf("size: %d bytes (%d left)\n", size, NVRAM_SPACE - size); 143 KFREE(buf); 144 } 145 146 return 0; 147} 148 149static int 150check_trx(void) 151{ 152 int ret; 153 fileio_ctx_t *fsctx; 154 void *ref; 155 struct trx_header trx; 156 uint32 crc, buf[128]; 157 unsigned int len, count; 158 159 /* Open header */ 160 ret = fs_init("raw", &fsctx, "flash0.trx"); 161 if (ret) 162 return ret; 163 164 ret = fs_open(fsctx, &ref, "", FILE_MODE_READ); 165 if (ret) { 166 fs_uninit(fsctx); 167 return ret; 168 } 169 170 /* Read header */ 171 ret = fs_read(fsctx, ref, (unsigned char *) &trx, sizeof(struct trx_header)); 172 if (ret != sizeof(struct trx_header)) { 173 ret = CFE_ERR_IOERR; 174 goto done; 175 } 176 177 /* Verify magic number */ 178 if (ltoh32(trx.magic) != TRX_MAGIC) { 179 ret = CFE_ERR_INVBOOTBLOCK; 180 goto done; 181 } 182 183 /* Checksum over header */ 184 crc = hndcrc32((uint8 *) &trx.flag_version, 185 sizeof(struct trx_header) - OFFSETOF(struct trx_header, flag_version), 186 CRC32_INIT_VALUE); 187 188 fs_close(fsctx, ref); 189 fs_uninit(fsctx); 190 191 /* Open data */ 192 ret = fs_init("raw", &fsctx, "flash0.os"); 193 if (ret) 194 return ret; 195 196 ret = fs_open(fsctx, &ref, "", FILE_MODE_READ); 197 if (ret) { 198 fs_uninit(fsctx); 199 return ret; 200 } 201 202 for (len = ltoh32(trx.len) - sizeof(struct trx_header); len; len -= count) { 203 count = MIN(len, sizeof(buf)); 204 205 /* Read data */ 206 ret = fs_read(fsctx, ref, (unsigned char *) &buf, count); 207 if (ret != count) { 208 ret = CFE_ERR_IOERR; 209 goto done; 210 } 211 212 /* Checksum over data */ 213 crc = hndcrc32((uint8 *) &buf, count, crc); 214 } 215 216 /* Verify checksum */ 217 if (ltoh32(trx.crc32) != crc) { 218 ret = CFE_ERR_BOOTPROGCHKSUM; 219 goto done; 220 } 221 222 ret = 0; 223 224 done: 225 fs_close(fsctx, ref); 226 fs_uninit(fsctx); 227 if (ret) 228 xprintf("%s\n", cfe_errortext(ret)); 229 return ret; 230} 231 232/* ********************************************************************* 233 * ui_get_loadbuf(bufptr, bufsize) 234 * 235 * Figure out the location and size of the staging buffer. 236 * 237 * Input parameters: 238 * bufptr - address to return buffer location 239 * bufsize - address to return buffer size 240 ********************************************************************* */ 241static void ui_get_loadbuf(uint8_t **bufptr, int *bufsize) 242{ 243 int size = CFG_FLASH_STAGING_BUFFER_SIZE; 244 245 /* 246 * Get the address of the staging buffer. We can't 247 * allocate the space from the heap to store the 248 * new flash image, because the heap may not be big 249 * enough. So, if FLASH_STAGING_BUFFER_SIZE is non-zero 250 * then just use it and FLASH_STAGING_BUFFER; else 251 * use the larger of (mem_bottomofmem - FLASH_STAGING_BUFFER) 252 * and (mem_totalsize - mem_topofmem). 253 */ 254 255 if (size > 0) { 256 *bufptr = (uint8_t *) KERNADDR(CFG_FLASH_STAGING_BUFFER_ADDR); 257 *bufsize = size; 258 } else { 259 int below, above; 260 261 below = PHYSADDR(mem_bottomofmem) - CFG_FLASH_STAGING_BUFFER_ADDR; 262 above = (mem_totalsize << 10) - PHYSADDR(mem_topofmem); 263 264 if (below > above) { 265 *bufptr = (uint8_t *) KERNADDR(CFG_FLASH_STAGING_BUFFER_ADDR); 266 *bufsize = below; 267 } else { 268 *bufptr = (uint8_t *) KERNADDR(mem_topofmem); 269 *bufsize = above; 270 } 271 } 272} 273 274static int 275ui_cmd_go(ui_cmdline_t *cmd, int argc, char *argv[]) 276{ 277 int ret = 0; 278 char buf[512]; 279 struct trx_header *file_buf; 280 uint8_t *ptr; 281 int bufsize = 0; 282 283 if (check_trx()) { 284 /* Wait forever for an image */ 285 while ((ret = ui_docommand("flash -noheader : flash1.trx")) == CFE_ERR_TIMEOUT); 286 } else if (!nvram_invmatch("boot_wait", "on")) { 287 ui_get_loadbuf(&ptr, &bufsize); 288 /* Load the image */ 289 sprintf(buf, "load -raw -addr=0x%x -max=0x%x :", ptr, TRX_MAX_LEN); 290 ret = ui_docommand(buf); 291 292 /* Load was successful. Check for the TRX magic. 293 * If it's a TRX image, then proceed to flash it, else try to boot 294 * Note: To boot a TRX image directly from the memory, address will need to be 295 * load address + trx header length. 296 */ 297 if (ret == 0) { 298 file_buf = (struct trx_header *)ptr; 299 /* If it's a TRX, then proceed to writing to flash else, 300 * try to boot from memory 301 */ 302 if (file_buf->magic != TRX_MAGIC) { 303 sprintf(buf, "boot -raw -z -addr=0x%s -max=0x%x -fs=memory :0x%x", 304 nvram_get("os_ram_addr") ? : "80001000", 305 TRX_MAX_LEN, ptr); 306 return ui_docommand(buf); 307 } 308 /* Flash the image from memory directly */ 309 sprintf(buf, "flash -noheader -mem -size=0x%x 0x%x flash1.trx", 310 file_buf->len, ptr); 311 ret = ui_docommand(buf); 312 } 313 } 314 315 if (ret == CFE_ERR_INTR) 316 return ret; 317 318 /* Boot the image */ 319 sprintf(buf, "boot -raw -z -addr=0x%s -max=0x%x flash0.os:", 320 nvram_get("os_ram_addr") ? : "80001000", 321 TRX_MAX_LEN); 322 return ui_docommand(buf); 323} 324 325 326int 327ui_init_bcm947xxcmds(void) 328{ 329 cmd_addcmd("reboot", 330 ui_cmd_reboot, 331 NULL, 332 "Reboot.", 333 "reboot\n\n" 334 "Reboots.", 335 ""); 336 cmd_addcmd("nvram", 337 ui_cmd_nvram, 338 NULL, 339 "NVRAM utility.", 340#ifndef CFG_MINIMAL_SIZE 341 "nvram [command] [args..]\n\n" 342 "Access NVRAM.", 343 "get [name];Gets the value of the specified variable|" 344 "set [name=value];Sets the value of the specified variable|" 345 "unset [name];Deletes the specified variable|" 346 "commit;Commit variables to flash|" 347 "erase;Erase all nvram|" 348 "show;Shows all variables|" 349#else /* CFG_MINIMAL_SIZE */ 350 "nvram [command] [args..]\n", 351 "get [name];|" 352 "set [name=value];|" 353 "unset [name];|" 354 "commit;|" 355 "erase;|" 356 "show;|" 357#endif /* CFG_MINIMAL_SIZE */ 358 ); 359 cmd_addcmd("go", 360 ui_cmd_go, 361 NULL, 362 "Verify and boot OS image.", 363#ifndef CFG_MINIMAL_SIZE 364 "go\n\n" 365 "Boots OS image if valid. Waits for a new OS image if image is invalid\n" 366 "or boot_wait is unset or not on.", 367#else /* CFG_MINIMAL_SIZE */ 368 "go\n", 369#endif /* CFG_MINIMAL_SIZE */ 370 ""); 371#if CFG_ET 372 et_addcmd(); 373#endif 374#if CFG_WLU 375 wl_addcmd(); 376#endif 377 378 return 0; 379} 380