static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { bool dfu_reset = false; if (argc < 4) return CMD_RET_USAGE; char *usb_controller = argv[1]; char *interface = argv[2]; char *devstring = argv[3]; int ret, i = 0; ret = dfu_init_env_entities(interface, devstring); if (ret) goto done; ret = CMD_RET_SUCCESS; if (argc > 4 && strcmp(argv[4], "list") == 0) { dfu_show_entities(); goto done; } int controller_index = simple_strtoul(usb_controller, NULL, 0); board_usb_init(controller_index, USB_INIT_DEVICE); g_dnl_clear_detach(); g_dnl_register("usb_dnl_dfu"); while (1) { if (g_dnl_detach()) { /* * Check if USB bus reset is performed after detach, * which indicates that -R switch has been passed to * dfu-util. In this case reboot the device */ if (dfu_usb_get_reset()) { dfu_reset = true; goto exit; } /* * This extra number of usb_gadget_handle_interrupts() * calls is necessary to assure correct transmission * completion with dfu-util */ if (++i == 10000) goto exit; } if (ctrlc()) goto exit; WATCHDOG_RESET(); usb_gadget_handle_interrupts(controller_index); } exit: g_dnl_unregister(); board_usb_cleanup(controller_index, USB_INIT_DEVICE); done: dfu_free_entities(); if (dfu_reset) run_command("reset", 0); g_dnl_clear_detach(); return ret; }
/* * Returns 1 if keys pressed to start the power-on long-running tests * Called from board_init_f(). */ int post_hotkeys_pressed(void) { return (ctrlc()); }
int _do_help (cmd_tbl_t *cmd_start, int cmd_items, cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { int i; int rcode = 0; if (argc == 1) { /*show list of commands */ cmd_tbl_t *cmd_array[cmd_items]; int i, j, swaps; /* Make array of commands from .uboot_cmd section */ cmdtp = cmd_start; for (i = 0; i < cmd_items; i++) { cmd_array[i] = cmdtp++; } /* Sort command list (trivial bubble sort) */ for (i = cmd_items - 1; i > 0; --i) { swaps = 0; for (j = 0; j < i; ++j) { if (strcmp (cmd_array[j]->name, cmd_array[j + 1]->name) > 0) { cmd_tbl_t *tmp; tmp = cmd_array[j]; cmd_array[j] = cmd_array[j + 1]; cmd_array[j + 1] = tmp; ++swaps; } } if (!swaps) break; } /* print short help (usage) */ for (i = 0; i < cmd_items; i++) { const char *usage = cmd_array[i]->usage; /* allow user abort */ if (ctrlc ()) return 1; if (usage == NULL) continue; printf("%-*s- %s\n", CONFIG_SYS_HELP_CMD_WIDTH, cmd_array[i]->name, usage); } return 0; } /* * command help (long version) */ for (i = 1; i < argc; ++i) { if ((cmdtp = find_cmd_tbl (argv[i], cmd_start, cmd_items )) != NULL) { rcode |= cmd_usage(cmdtp); } else { printf ("Unknown command '%s' - try 'help'" " without arguments for list of all" " known commands\n\n", argv[i] ); rcode = 1; } } return rcode; }
int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong addr, length; ulong i, nbytes, linebytes; u_char *cp; int size; int rc = 0; /* We use the last specified parameters, unless new ones are * entered. */ addr = dp_last_addr; size = dp_last_size; length = dp_last_length; if (argc < 2) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } if ((flag & CMD_FLAG_REPEAT) == 0) { /* New command specified. Check for a size specification. * Defaults to long if no or incorrect specification. */ if ((size = cmd_get_data_size(argv[0], 4)) < 0) return 1; /* Address is specified since argc > 1 */ addr = simple_strtoul(argv[1], NULL, 16); addr += base_address; /* If another parameter, it is the length to display. * Length is the number of objects, not number of bytes. */ if (argc > 2) length = simple_strtoul(argv[2], NULL, 16); } /* Print the lines. * * We buffer all read data, so we can make sure data is read only * once, and all accesses are with the specified bus width. */ nbytes = length * size; do { char linebuf[DISP_LINE_LEN]; uint *uip = (uint *)linebuf; ushort *usp = (ushort *)linebuf; u_char *ucp = (u_char *)linebuf; #ifdef CONFIG_HAS_DATAFLASH int rc; #endif printf("%08lx:", addr); linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes; #ifdef CONFIG_HAS_DATAFLASH if ((rc = read_dataflash(addr, (linebytes/size)*size, linebuf)) == DATAFLASH_OK){ /* if outside dataflash */ /*if (rc != 1) { dataflash_perror (rc); return (1); }*/ for (i=0; i<linebytes; i+= size) { if (size == 4) { printf(" %08x", *uip++); } else if (size == 2) { printf(" %04x", *usp++); } else { printf(" %02x", *ucp++); } addr += size; } } else { /* addr does not correspond to DataFlash */ #endif for (i=0; i<linebytes; i+= size) { if (size == 4) { printf(" %08x", (*uip++ = *((uint *)addr))); } else if (size == 2) { printf(" %04x", (*usp++ = *((ushort *)addr))); } else { printf(" %02x", (*ucp++ = *((u_char *)addr))); } addr += size; } #ifdef CONFIG_HAS_DATAFLASH } #endif puts (" "); cp = (u_char *)linebuf; for (i=0; i<linebytes; i++) { if ((*cp < 0x20) || (*cp > 0x7e)) putc ('.'); else printf("%c", *cp); cp++; } putc ('\n'); nbytes -= linebytes; if (ctrlc()) { rc = 1; break; } } while (nbytes > 0); dp_last_addr = addr; dp_last_length = length; dp_last_size = size; return (rc); }
/************************************************************************ * Command interface: print one or all environment variables */ int do_printenv(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ int i, j, k, nxt; int rcode = 0; if(argc == 1){ /* Print all env variables */ for(i = 0; env_get_char(i) != '\0'; i = nxt + 1){ for(nxt = i; env_get_char(nxt) != '\0'; ++nxt); for(k = i; k < nxt; ++k){ putc(env_get_char(k)); } putc('\n'); if(ctrlc()){ puts("\nAbort\n"); return(1); } } #if defined(CFG_ENV_IS_IN_NVRAM) || \ defined(CFG_ENV_IS_IN_EEPROM) || \ ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == (CFG_CMD_ENV|CFG_CMD_FLASH)) || \ ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_NAND)) == (CFG_CMD_ENV|CFG_CMD_NAND)) printf("\nEnvironment size: %d/%d bytes\n\n", i, ENV_SIZE); #else printf("\nEnvironment size: %d bytes\n\n", i); #endif return(0); } for(i = 1; i < argc; ++i){ /* print single env variables */ char *name = argv[i]; k = -1; for(j = 0; env_get_char(j) != '\0'; j = nxt + 1){ for(nxt = j; env_get_char(nxt) != '\0'; ++nxt); k = envmatch((uchar *)name, j); if(k < 0){ continue; } puts(name); putc('='); while(k < nxt){ putc(env_get_char(k++)); } putc('\n'); break; } if(k < 0){ printf("## Error: \"%s\" not defined\n", name); rcode++; } } return(rcode); }
int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong addr, length; #if defined(CONFIG_HAS_DATAFLASH) ulong nbytes, linebytes; #endif int size; int rc = 0; /* We use the last specified parameters, unless new ones are * entered. */ addr = dp_last_addr; size = dp_last_size; length = dp_last_length; if (argc < 2) { cmd_usage(cmdtp); return 1; } if ((flag & CMD_FLAG_REPEAT) == 0) { /* New command specified. Check for a size specification. * Defaults to long if no or incorrect specification. */ if ((size = cmd_get_data_size(argv[0], 4)) < 0) return 1; /* Address is specified since argc > 1 */ addr = simple_strtoul(argv[1], NULL, 16); addr += base_address; /* If another parameter, it is the length to display. * Length is the number of objects, not number of bytes. */ if (argc > 2) length = simple_strtoul(argv[2], NULL, 16); } #if defined(CONFIG_HAS_DATAFLASH) /* Print the lines. * * We buffer all read data, so we can make sure data is read only * once, and all accesses are with the specified bus width. */ nbytes = length * size; do { char linebuf[DISP_LINE_LEN]; void* p; linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes; rc = read_dataflash(addr, (linebytes/size)*size, linebuf); p = (rc == DATAFLASH_OK) ? linebuf : (void*)addr; print_buffer(addr, p, size, linebytes/size, DISP_LINE_LEN/size); nbytes -= linebytes; addr += linebytes; if (ctrlc()) { rc = 1; break; } } while (nbytes > 0); #else # if defined(CONFIG_BLACKFIN) /* See if we're trying to display L1 inst */ if (addr_bfin_on_chip_mem(addr)) { char linebuf[DISP_LINE_LEN]; ulong linebytes, nbytes = length * size; do { linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes; memcpy(linebuf, (void *)addr, linebytes); print_buffer(addr, linebuf, size, linebytes/size, DISP_LINE_LEN/size); nbytes -= linebytes; addr += linebytes; if (ctrlc()) { rc = 1; break; } } while (nbytes > 0); } else # endif { /* Print the lines. */ print_buffer(addr, (void*)addr, size, length, DISP_LINE_LEN/size); addr += size*length; } #endif dp_last_addr = addr; dp_last_length = length; dp_last_size = size; return (rc); }
/* * this is called from board_init() after the hardware has been set up * and is usable. That seems like a good time to do this. * Right now the return value is ignored. */ int do_auto_update(void) { block_dev_desc_t *stor_dev; long sz; int i, res = 0, cnt, old_ctrlc; char *env; long start, end; #if 0 /* disable key-press detection to speed up boot-up time */ uchar keypad_status1[2] = {0,0}, keypad_status2[2] = {0,0}; /* * Read keypad status */ i2c_read(I2C_PSOC_KEYPAD_ADDR, 0, 0, keypad_status1, 2); mdelay(500); i2c_read(I2C_PSOC_KEYPAD_ADDR, 0, 0, keypad_status2, 2); /* * Check keypad */ if ( !(keypad_status1[1] & KEYPAD_MASK_LO) || (keypad_status1[1] != keypad_status2[1])) { return 0; } #endif au_usb_stor_curr_dev = -1; /* start USB */ if (usb_stop() < 0) { debug ("usb_stop failed\n"); return -1; } if (usb_init() < 0) { debug ("usb_init failed\n"); return -1; } /* * check whether a storage device is attached (assume that it's * a USB memory stick, since nothing else should be attached). */ au_usb_stor_curr_dev = usb_stor_scan(0); if (au_usb_stor_curr_dev == -1) { debug ("No device found. Not initialized?\n"); res = -1; goto xit; } /* check whether it has a partition table */ stor_dev = get_dev("usb", 0); if (stor_dev == NULL) { debug ("uknown device type\n"); res = -1; goto xit; } if (fat_register_device(stor_dev, 1) != 0) { debug ("Unable to use USB %d:%d for fatls\n", au_usb_stor_curr_dev, 1); res = -1; goto xit; } if (file_fat_detectfs() != 0) { debug ("file_fat_detectfs failed\n"); } /* * now check whether start and end are defined using environment * variables. */ start = -1; end = 0; env = getenv("firmware_st"); if (env != NULL) start = simple_strtoul(env, NULL, 16); env = getenv("firmware_nd"); if (env != NULL) end = simple_strtoul(env, NULL, 16); if (start >= 0 && end && end > start) { ausize[IDX_FIRMWARE] = (end + 1) - start; aufl_layout[IDX_FIRMWARE].start = start; aufl_layout[IDX_FIRMWARE].end = end; } start = -1; end = 0; env = getenv("kernel_st"); if (env != NULL) start = simple_strtoul(env, NULL, 16); env = getenv("kernel_nd"); if (env != NULL) end = simple_strtoul(env, NULL, 16); if (start >= 0 && end && end > start) { ausize[IDX_KERNEL] = (end + 1) - start; aufl_layout[IDX_KERNEL].start = start; aufl_layout[IDX_KERNEL].end = end; } start = -1; end = 0; env = getenv("rootfs_st"); if (env != NULL) start = simple_strtoul(env, NULL, 16); env = getenv("rootfs_nd"); if (env != NULL) end = simple_strtoul(env, NULL, 16); if (start >= 0 && end && end > start) { ausize[IDX_ROOTFS] = (end + 1) - start; aufl_layout[IDX_ROOTFS].start = start; aufl_layout[IDX_ROOTFS].end = end; } /* make certain that HUSH is runnable */ u_boot_hush_start(); /* make sure that we see CTRL-C and save the old state */ old_ctrlc = disable_ctrlc(0); /* validate the images first */ for (i = 0; i < AU_MAXFILES; i++) { ulong imsize; /* just read the header */ sz = file_fat_read(aufile[i], LOAD_ADDR, image_get_header_size ()); debug ("read %s sz %ld hdr %d\n", aufile[i], sz, image_get_header_size ()); if (sz <= 0 || sz < image_get_header_size ()) { debug ("%s not found\n", aufile[i]); ausize[i] = 0; continue; } /* au_check_header_valid() updates ausize[] */ if ((imsize = au_check_header_valid(i, sz)) < 0) { debug ("%s header not valid\n", aufile[i]); continue; } /* totsize accounts for image size and flash erase size */ totsize += (imsize + (aufl_layout[i].end - aufl_layout[i].start)); } #ifdef CONFIG_PROGRESSBAR if (totsize) { lcd_puts(" Update in progress\n"); lcd_enable(); } #endif /* just loop thru all the possible files */ for (i = 0; i < AU_MAXFILES && totsize; i++) { if (!ausize[i]) { continue; } sz = file_fat_read(aufile[i], LOAD_ADDR, ausize[i]); debug ("read %s sz %ld hdr %d\n", aufile[i], sz, image_get_header_size ()); if (sz != ausize[i]) { printf ("%s: size %ld read %ld?\n", aufile[i], ausize[i], sz); continue; } if (sz <= 0 || sz <= image_get_header_size ()) { debug ("%s not found\n", aufile[i]); continue; } if (au_check_cksum_valid(i, sz) < 0) { debug ("%s checksum not valid\n", aufile[i]); continue; } /* this is really not a good idea, but it's what the */ /* customer wants. */ cnt = 0; do { res = au_do_update(i, sz); /* let the user break out of the loop */ if (ctrlc() || had_ctrlc()) { clear_ctrlc(); break; } cnt++; #ifdef AU_TEST_ONLY } while (res < 0 && cnt < (AU_MAXFILES + 1)); if (cnt < (AU_MAXFILES + 1)) #else } while (res < 0); #endif }
/* * Command loadpci: wait for signal from host and boot image. */ int do_loadpci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { u32 *ptr = 0; int count = 0; int count2 = 0; char addr[16]; char str[] = "\\|/-"; u32 la, ptm1la; #if defined(CONFIG_440) ptm1la = in32r(PCIL0_PTM1LA); #else ptm1la = in32r(PTM1LA); #endif while(1) { /* * Mark sync address */ ptr = (u32 *)ptm1la; memset(ptr, 0, 0x20); *ptr = 0xffffffff; puts("\nWaiting for action from pci host -"); /* * Wait for host to write the start address */ while (*ptr == 0xffffffff) { count++; if (!(count % 100)) { count2++; putc(0x08); /* backspace */ putc(str[count2 % 4]); } /* Abort if ctrl-c was pressed */ if (ctrlc()) { puts("\nAbort\n"); return 0; } udelay(1000); } printf("\nGot bootcode %08x: ", *ptr); la = ptm1la + (*ptr & ADDRMASK); sprintf(addr, "%08x", la); switch (*ptr & ~ADDRMASK) { case 0: /* * Boot image via bootm */ printf("booting image at addr 0x%s ...\n", addr); setenv("loadaddr", addr); do_bootm(cmdtp, 0, 0, NULL); break; case 1: /* * Boot image via "source" command */ printf("executing script at addr 0x%s ...\n", addr); source(la, NULL); break; case 2: /* * Call run_cmd */ printf("running command at addr 0x%s ...\n", addr); run_command((char *)la, 0); break; default: printf("unhandled boot method\n"); break; } } }
/* * Use puts() instead of printf() to avoid printf buffer overflow * for long help messages */ int do_help (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { int i; int rcode = 0; if (argc == 1) { /*show list of commands */ int cmd_items = &__u_boot_cmd_end - &__u_boot_cmd_start; /* pointer arith! */ cmd_tbl_t *cmd_array[cmd_items]; int i, j, swaps; /* Make array of commands from .uboot_cmd section */ cmdtp = &__u_boot_cmd_start; for (i = 0; i < cmd_items; i++) { cmd_array[i] = cmdtp++; } /* Sort command list (trivial bubble sort) */ for (i = cmd_items - 1; i > 0; --i) { swaps = 0; for (j = 0; j < i; ++j) { if (strcmp (cmd_array[j]->name, cmd_array[j + 1]->name) > 0) { cmd_tbl_t *tmp; tmp = cmd_array[j]; cmd_array[j] = cmd_array[j + 1]; cmd_array[j + 1] = tmp; ++swaps; } } if (!swaps) break; } /* print short help (usage) */ for (i = 0; i < cmd_items; i++) { const char *usage = cmd_array[i]->usage; /* allow user abort */ if (ctrlc ()) return 1; if (usage == NULL) continue; puts (usage); } return 0; } /* * command help (long version) */ for (i = 1; i < argc; ++i) { if ((cmdtp = find_cmd (argv[i])) != NULL) { #ifdef CFG_LONGHELP /* found - print (long) help info */ puts (cmdtp->name); putc (' '); if (cmdtp->help) { puts (cmdtp->help); } else { puts ("- No help available.\n"); rcode = 1; } putc ('\n'); #else /* no long help available */ if (cmdtp->usage) puts (cmdtp->usage); #endif /* CFG_LONGHELP */ } else { printf ("Unknown command '%s' - try 'help'" " without arguments for list of all" " known commands\n\n", argv[i] ); rcode = 1; } } return rcode; }
int do_fastboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { int ret = 1; char fbparts[4096], *env; int check_timeout = 0; uint64_t timeout_endtime = 0; uint64_t timeout_ticks = 0; long timeout_seconds = -1; int continue_from_disconnect = 0; /* * Place the runtime partitions at the end of the * static paritions. First save the start off so * it can be saved from run to run. */ if (static_pcount >= 0) { /* Reset */ pcount = static_pcount; } else { /* Save */ static_pcount = pcount; } env = getenv("fbparts"); if (env) { unsigned int len; len = strlen(env); if (len && len < 4096) { char *s, *e; memcpy(&fbparts[0], env, len + 1); printf("Fastboot: Adding partitions from environment\n"); s = &fbparts[0]; e = s + len; while (s < e) { if (add_partition_from_environment(s, &s)) { printf("Error:Fastboot: Abort adding partitions\n"); /* reset back to static */ pcount = static_pcount; break; } /* Skip a bunch of delimiters */ while (s < e) { if ((' ' == *s) || ('\t' == *s) || ('\n' == *s) || ('\r' == *s) || (',' == *s)) { s++; } else { break; } } } } } /* Time out */ if (2 == argc) { long try_seconds; char *try_seconds_end; /* Check for timeout */ try_seconds = simple_strtol(argv[1], &try_seconds_end, 10); if ((try_seconds_end != argv[1]) && (try_seconds >= 0)) { check_timeout = 1; timeout_seconds = try_seconds; printf("Fastboot inactivity timeout %ld seconds\n", timeout_seconds); } } if (1 == check_timeout) { timeout_ticks = (uint64_t) (timeout_seconds * get_tbclk()); } do { continue_from_disconnect = 0; /* Initialize the board specific support */ if (0 == fastboot_init(&interface)) { int poll_status; /* If we got this far, we are a success */ ret = 0; printf("fastboot initialized\n"); timeout_endtime = get_ticks(); timeout_endtime += timeout_ticks; while (1) { uint64_t current_time = 0; poll_status = fastboot_poll(); if (1 == check_timeout) current_time = get_ticks(); if (FASTBOOT_ERROR == poll_status) { /* Error */ break; } else if (FASTBOOT_DISCONNECT == poll_status) { /* beak, cleanup and re-init */ printf("Fastboot disconnect detected\n"); continue_from_disconnect = 1; break; } else if ((1 == check_timeout) && (FASTBOOT_INACTIVE == poll_status)) { /* No activity */ if (current_time >= timeout_endtime) { printf("Fastboot inactivity detected\n"); break; } } else { /* Something happened */ if (1 == check_timeout) { /* Update the timeout endtime */ timeout_endtime = current_time; timeout_endtime += timeout_ticks; } } /* Check if the user wanted to terminate with ^C */ if ((FASTBOOT_INACTIVE == poll_status) && (ctrlc())) { printf("Fastboot ended by user\n"); break; } /* * Check if the fastboot client wanted to * continue booting */ if (continue_booting) { printf("Fastboot ended by client\n"); break; } /* Check if there is something to upload */ tx_handler(); } } /* Reset the board specific support */ fastboot_shutdown(); /* restart the loop if a disconnect was detected */ } while (continue_from_disconnect); return ret; }
static int run_list_real(struct pipe *pi) { char *save_name = NULL; char **list = NULL; char **save_list = NULL; struct pipe *rpipe; int flag_rep = 0; int rcode = 0, flag_skip = 1; int flag_restore = 0; int if_code = 0, next_if_code = 0; /* need double-buffer to handle elif */ reserved_style rmode, skip_more_in_this_rmode = RES_XXXX; /* check syntax for "for" */ for (rpipe = pi; rpipe; rpipe = rpipe->next) { if ((rpipe->r_mode == RES_IN || rpipe->r_mode == RES_FOR) && (rpipe->next == NULL)) { syntax(); flag_repeat = 0; return 1; } if ((rpipe->r_mode == RES_IN && (rpipe->next->r_mode == RES_IN && rpipe->next->progs->argv != NULL)) || (rpipe->r_mode == RES_FOR && rpipe->next->r_mode != RES_IN)) { syntax(); flag_repeat = 0; return 1; } } for (; pi; pi = (flag_restore != 0) ? rpipe : pi->next) { if (pi->r_mode == RES_WHILE || pi->r_mode == RES_UNTIL || pi->r_mode == RES_FOR) { /* check Ctrl-C */ ctrlc(); if ((had_ctrlc())) { return 1; } flag_restore = 0; if (!rpipe) { flag_rep = 0; rpipe = pi; } } rmode = pi->r_mode; debug_printf("rmode=%d if_code=%d next_if_code=%d skip_more=%d\n", rmode, if_code, next_if_code, skip_more_in_this_rmode); if (rmode == skip_more_in_this_rmode && flag_skip) { if (pi->followup == PIPE_SEQ) flag_skip = 0; continue; } flag_skip = 1; skip_more_in_this_rmode = RES_XXXX; if (rmode == RES_THEN || rmode == RES_ELSE) if_code = next_if_code; if (rmode == RES_THEN && if_code) continue; if (rmode == RES_ELSE && !if_code) continue; if (rmode == RES_ELIF && !if_code) break; if (rmode == RES_FOR && pi->num_progs) { if (!list) { /* if no variable values after "in" we skip "for" */ if (!pi->next->progs->argv) continue; /* create list of variable values */ list = make_list_in(pi->next->progs->argv, pi->progs->argv[0]); save_list = list; save_name = pi->progs->argv[0]; pi->progs->argv[0] = NULL; flag_rep = 1; } if (!(*list)) { free(pi->progs->argv[0]); free(save_list); list = NULL; flag_rep = 0; pi->progs->argv[0] = save_name; continue; } else { /* insert new value from list for variable */ if (pi->progs->argv[0]) free(pi->progs->argv[0]); pi->progs->argv[0] = *list++; } } if (rmode == RES_IN) continue; if (rmode == RES_DO) { if (!flag_rep) continue; } if ((rmode == RES_DONE)) { if (flag_rep) { flag_restore = 1; } else { rpipe = NULL; } } if (pi->num_progs == 0) continue; rcode = run_pipe_real(pi); debug_printf("run_pipe_real returned %d\n", rcode); if (rcode < -1) { last_return_code = -rcode - 2; return -2; /* exit */ } last_return_code = (rcode == 0) ? 0 : 1; if (rmode == RES_IF || rmode == RES_ELIF) next_if_code = rcode; /* can be overwritten a number of times */ if (rmode == RES_WHILE) flag_rep = !last_return_code; if (rmode == RES_UNTIL) flag_rep = last_return_code; if ((rcode == EXIT_SUCCESS && pi->followup == PIPE_OR) || (rcode != EXIT_SUCCESS && pi->followup == PIPE_AND)) skip_more_in_this_rmode = rmode; } return rcode; }
static void parse_bank(ulong bank) { int i; ulong flstart, flend; flash_info_t *info; info = &flash_info[bank]; if (info->flash_id != FLASH_MAN_CFI) { printf("Bank %lu: missing or unknown FLASH type\n", bank); return; } if (!info->sector_count) { printf("Bank %lu: no FLASH sectors\n", bank); return; } flstart = info->start[0]; flend = flstart + info->size; for (i = 0; i < info->sector_count; ++i) { ulong secend; u32 foot1, foot2; if (ctrlc()) break; if (i == info->sector_count-1) secend = flend; else secend = info->start[i+1]; /* Check for v1 header */ foot1 = readl((void *)secend - 0x0c); if (foot1 == 0xA0FFFF9FU) { struct afs_image *afi = &afs_images[num_afs_images]; ulong imginfo; afi->flinfo = info; afi->version = 1; afi->flash_mem_start = readl((void *)secend - 0x10); afi->flash_mem_end = readl((void *)secend - 0x14); afi->attributes = readl((void *)secend - 0x08); /* Adjust to even address */ imginfo = afi->flash_mem_end + afi->flash_mem_end % 4; /* Record as a single region */ afi->region_count = 1; afi->regions[0].offset = readl((void *)imginfo + 0x04); afi->regions[0].load_address = readl((void *)imginfo + 0x08); afi->regions[0].size = readl((void *)imginfo + 0x0C); afi->entrypoint = readl((void *)imginfo + 0x10); afi->name = (const char *)imginfo + 0x14; num_afs_images++; } /* Check for v2 header */ foot1 = readl((void *)secend - 0x04); foot2 = readl((void *)secend - 0x08); /* This makes up the string "HSLFTOOF" flash footer */ if (foot1 == 0x464F4F54U && foot2 == 0x464C5348U) { struct afs_image *afi = &afs_images[num_afs_images]; ulong imginfo; u32 block_start, block_end; int j; afi->flinfo = info; afi->version = readl((void *)secend - 0x0c); imginfo = secend - 0x30 - readl((void *)secend - 0x10); afi->name = (const char *)secend - 0x30; afi->entrypoint = readl((void *)imginfo+0x08); afi->attributes = readl((void *)imginfo+0x0c); afi->region_count = readl((void *)imginfo+0x10); block_start = readl((void *)imginfo+0x54); block_end = readl((void *)imginfo+0x58); afi->flash_mem_start = afi->flinfo->start[block_start]; afi->flash_mem_end = afi->flinfo->start[block_end]; /* * Check footer CRC, the algorithm saves the inverse * checksum as part of the summed words, and thus * the result should be zero. */ if (compute_crc(imginfo + 8, 0x88) != 0) { printf("BAD CRC on ARM image info\n"); printf("(continuing anyway)\n"); } /* Parse regions */ for (j = 0; j < afi->region_count; j++) { afi->regions[j].load_address = readl((void *)imginfo+0x14 + j*0x10); afi->regions[j].size = readl((void *)imginfo+0x18 + j*0x10); afi->regions[j].offset = readl((void *)imginfo+0x1c + j*0x10); /* * At offset 0x20 + j*0x10 there is a region * checksum which seems to be the running * sum + 3, however since we anyway checksum * the entire footer this is skipped over for * checking here. */ } num_afs_images++; } } }
/* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : * * ************************************************************************************************************ */ int do_burn_from_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct timer_list timer_t; int ret; if(gd->vbus_status == SUNXI_VBUS_NOT_EXIST) { printf("out of usb burn from boot without usb\n"); return 0; } tick_printf("usb burn from boot\n"); if(sunxi_usb_dev_register(4) < 0) { printf("usb burn fail: not support burn private data\n"); return -1; } sunxi_usb_burn_from_boot_overtime = 0; if(sunxi_usb_init(0)) { printf("%s usb init fail\n", __func__); sunxi_usb_exit(); return 0; } timer_t.data = (unsigned long)&timer_t; timer_t.expires = 800; timer_t.function = probe_usb_overtime; init_timer(&timer_t); tick_printf("usb prepare ok\n"); add_timer(&timer_t); while(1) { if(sunxi_usb_burn_from_boot_init) //当usb sof中断触发,跳出循环 { printf("usb sof ok\n"); del_timer(&timer_t); break; } if(sunxi_usb_burn_from_boot_overtime) //当定时时间到,还没有中断,跳出循环 { tick_printf("overtime\n"); del_timer(&timer_t); sunxi_usb_exit(); tick_printf("%s usb : no usb exist\n", __func__); return 0; } } sunxi_usb_burn_from_boot_overtime = 0; tick_printf("usb probe ok\n"); //开始等待加载驱动,这里不需要延时 sunxi_usb_burn_from_boot_overtime = 0; tick_printf("usb setup ok\n"); timer_t.expires = 3000; add_timer(&timer_t); while(1) { ret = sunxi_usb_extern_loop(); //执行usb主循环 if(ret) //当执行结果非0,表示到了最后一个步骤,需要往后执行 { break; } if(sunxi_usb_burn_from_boot_handshake) //当握手成功,停止检查定时器 { del_timer(&timer_t); } if(sunxi_usb_burn_from_boot_overtime) //当定时时间到,还没有握手成功,跳出循环 { del_timer(&timer_t); sunxi_usb_exit(); tick_printf("%s usb : have no handshake\n", __func__); return 0; } if(ctrlc()) { del_timer(&timer_t); ret = SUNXI_UPDATE_NEXT_ACTION_NORMAL; break; } if(sunxi_key_read()>0) { del_timer(&timer_t); ret = SUNXI_UPDATE_NEXT_ACTION_NORMAL; break; } } tick_printf("exit usb burn from boot\n"); sunxi_usb_exit(); sunxi_update_subsequent_processing(ret); return 0; }
static int memtest(int argc, char ** argv) { u32_t base, size; u32_t * start, * end; u32_t walker, readback, *i; s32_t errcnt = 0; if(argc == 1) { base = 0; base = base & (~0x00000003); size = 0; size = size & (~0x00000003); } else if(argc == 3) { base = strtoul((const char *)argv[1], NULL, 0); base = base & (~0x00000003); size = strtoul((const char *)argv[2], NULL, 0); size = size & (~0x00000003); } else { printk("usage:\r\n memtest <address> <size>\r\n"); return (-1); } printk("testing 0x%08lx .. 0x%08lx\r\n", base, base + size); start = (u32_t *)base; if(size == 0) { printk("not do any testing\r\n"); return 0; } /* walker one test */ walker = 0x1; end = start + 32; for(i = start; i < end; i++) { *i = walker; walker <<= 1; } walker = 0x1; for(i = start; i < end; i++) { readback = *i; if(readback != walker) { errcnt++; printk("error at 0x%08lx: read 0x%lx expected x%lx\r\n", (u32_t)i, readback, walker); break; } walker <<= 1; } /* address in address test */ end = (u32_t *)((u32_t)start + size); for(i = start; i < end; i++) { if(((u32_t)i & 0x3ffff) == 0) { if(ctrlc()) return -1; } *i = (u32_t)i; } for(i = start; i < end; i++) { if(((u32_t)i & 0x3ffff) == 0) { if(ctrlc()) return -1; } readback = *i; if(readback != (u32_t)i) { errcnt++; printk("error at 0x%08lx: read 0x%08lx expected 0x%08lx\r\n", (u32_t)i, readback, (u32_t)i); break; } } if(errcnt > 0) printk("found %d errors\r\n", errcnt); else printk("no found any errors\r\n"); return 0; }
/* * Virtex-II Slave SelectMap configuration loader. Configuration via * SelectMap is as follows: * 1. Set the FPGA's PROG_B line low. * 2. Set the FPGA's PROG_B line high. Wait for INIT_B to go high. * 3. Write data to the SelectMap port. If INIT_B goes low at any time * this process, a configuration error (most likely CRC failure) has * ocurred. At this point a status word may be read from the * SelectMap interface to determine the source of the problem (You * could, for instance, put this in your 'abort' function handler). * 4. After all data has been written, test the state of the FPGA * INIT_B and DONE lines. If both are high, configuration has * succeeded. Congratulations! */ static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize) { int ret_val = FPGA_FAIL; Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns; PRINTF ("%s:%d: Start with interface functions @ 0x%p\n", __FUNCTION__, __LINE__, fn); if (fn) { size_t bytecount = 0; unsigned char *data = (unsigned char *) buf; int cookie = desc->cookie; unsigned long ts; /* Gotta split this one up (so the stack won't blow??) */ PRINTF ("%s:%d: Function Table:\n" " base 0x%p\n" " struct 0x%p\n" " pre 0x%p\n" " prog 0x%p\n" " init 0x%p\n" " error 0x%p\n", __FUNCTION__, __LINE__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err); PRINTF (" clock 0x%p\n" " cs 0x%p\n" " write 0x%p\n" " rdata 0x%p\n" " wdata 0x%p\n" " busy 0x%p\n" " abort 0x%p\n" " post 0x%p\n\n", fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy, fn->abort, fn->post); #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK printf ("Initializing FPGA Device %d...\n", cookie); #endif /* * Run the pre configuration function if there is one. */ if (*fn->pre) { (*fn->pre) (cookie); } /* * Assert the program line. The minimum pulse width for * Virtex II devices is 300 nS (Tprogram parameter in datasheet). * There is no maximum value for the pulse width. Check to make * sure that INIT_B goes low after assertion of PROG_B */ (*fn->pgm) (TRUE, TRUE, cookie); udelay (10); ts = get_timer (0); do { if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) { printf ("%s:%d: ** Timeout after %d ticks waiting for INIT" " to assert.\n", __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_INIT); (*fn->abort) (cookie); return FPGA_FAIL; } } while (!(*fn->init) (cookie)); (*fn->pgm) (FALSE, TRUE, cookie); CONFIG_FPGA_DELAY (); (*fn->clk) (TRUE, TRUE, cookie); /* * Start a timer and wait for INIT_B to go high */ ts = get_timer (0); do { CONFIG_FPGA_DELAY (); if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) { printf ("%s:%d: ** Timeout after %d ticks waiting for INIT" " to deassert.\n", __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_INIT); (*fn->abort) (cookie); return FPGA_FAIL; } } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); (*fn->wr) (TRUE, TRUE, cookie); (*fn->cs) (TRUE, TRUE, cookie); udelay (10000); /* * Load the data byte by byte */ while (bytecount < bsize) { #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC if (ctrlc ()) { (*fn->abort) (cookie); return FPGA_FAIL; } #endif if ((*fn->done) (cookie) == FPGA_SUCCESS) { PRINTF ("%s:%d:done went active early, bytecount = %d\n", __FUNCTION__, __LINE__, bytecount); break; } #ifdef CONFIG_SYS_FPGA_CHECK_ERROR if ((*fn->init) (cookie)) { printf ("\n%s:%d: ** Error: INIT asserted during" " configuration\n", __FUNCTION__, __LINE__); printf ("%d = buffer offset, %d = buffer size\n", bytecount, bsize); (*fn->abort) (cookie); return FPGA_FAIL; } #endif (*fn->wdata) (data[bytecount++], TRUE, cookie); CONFIG_FPGA_DELAY (); /* * Cycle the clock pin */ (*fn->clk) (FALSE, TRUE, cookie); CONFIG_FPGA_DELAY (); (*fn->clk) (TRUE, TRUE, cookie); #ifdef CONFIG_SYS_FPGA_CHECK_BUSY ts = get_timer (0); while ((*fn->busy) (cookie)) { if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_BUSY) { printf ("%s:%d: ** Timeout after %d ticks waiting for" " BUSY to deassert\n", __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_BUSY); (*fn->abort) (cookie); return FPGA_FAIL; } } #endif #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK if (bytecount % (bsize / 40) == 0) putc ('.'); #endif } /* * Finished writing the data; deassert FPGA CS_B and WRITE_B signals. */ CONFIG_FPGA_DELAY (); (*fn->cs) (FALSE, TRUE, cookie); (*fn->wr) (FALSE, TRUE, cookie); #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK putc ('\n'); #endif /* * Check for successful configuration. FPGA INIT_B and DONE should * both be high upon successful configuration. */ ts = get_timer (0); ret_val = FPGA_SUCCESS; while (((*fn->done) (cookie) == FPGA_FAIL) || (*fn->init) (cookie)) { if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) { printf ("%s:%d: ** Timeout after %d ticks waiting for DONE to" "assert and INIT to deassert\n", __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG); (*fn->abort) (cookie); ret_val = FPGA_FAIL; break; } } if (ret_val == FPGA_SUCCESS) { #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK printf ("Initialization of FPGA device %d complete\n", cookie); #endif /* * Run the post configuration function if there is one. */ if (*fn->post) { (*fn->post) (cookie); } } else { #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK printf ("** Initialization of FPGA device %d FAILED\n", cookie); #endif } } else { printf ("%s:%d: NULL Interface function table!\n", __FUNCTION__, __LINE__); } return ret_val; }
int run_usb_dnl_gadget(int usbctrl_index, char *usb_dnl_gadget) { bool dfu_reset = false; int ret, i = 0; board_usb_init(usbctrl_index, USB_INIT_DEVICE); g_dnl_clear_detach(); ret = g_dnl_register(usb_dnl_gadget); if (ret) { error("g_dnl_register failed"); return CMD_RET_FAILURE; } while (1) { if (g_dnl_detach()) { /* * Check if USB bus reset is performed after detach, * which indicates that -R switch has been passed to * dfu-util. In this case reboot the device */ if (dfu_usb_get_reset()) { dfu_reset = true; goto exit; } /* * This extra number of usb_gadget_handle_interrupts() * calls is necessary to assure correct transmission * completion with dfu-util */ if (++i == 10000) goto exit; } if (ctrlc()) goto exit; if (dfu_get_defer_flush()) { /* * Call to usb_gadget_handle_interrupts() is necessary * to act on ZLP OUT transaction from HOST PC after * transmitting the whole file. * * If this ZLP OUT packet is NAK'ed, the HOST libusb * function fails after timeout (by default it is set to * 5 seconds). In such situation the dfu-util program * exits with error message. */ usb_gadget_handle_interrupts(usbctrl_index); ret = dfu_flush(dfu_get_defer_flush(), NULL, 0, 0); dfu_set_defer_flush(NULL); if (ret) { error("Deferred dfu_flush() failed!"); goto exit; } } WATCHDOG_RESET(); usb_gadget_handle_interrupts(usbctrl_index); } exit: g_dnl_unregister(); board_usb_cleanup(usbctrl_index, USB_INIT_DEVICE); if (dfu_reset) run_command("reset", 0); g_dnl_clear_detach(); return ret; }
int dhcp(int retries, struct dhcp_req_param *param) { int ret = 0; dhcp_reset_env(); dhcp_set_param_data(DHCP_HOSTNAME, param->hostname); dhcp_set_param_data(DHCP_VENDOR_ID, param->vendor_id); dhcp_set_param_data(DHCP_CLIENT_ID, param->client_id); dhcp_set_param_data(DHCP_USER_CLASS, param->user_class); dhcp_set_param_data(DHCP_CLIENT_UUID, param->client_uuid); if (!retries) retries = DHCP_DEFAULT_RETRY; dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler, NULL); if (IS_ERR(dhcp_con)) { ret = PTR_ERR(dhcp_con); goto out; } ret = net_udp_bind(dhcp_con, PORT_BOOTPC); if (ret) goto out1; net_set_ip(0); dhcp_start = get_time_ns(); ret = bootp_request(); /* Basically same as BOOTP */ if (ret) goto out1; while (dhcp_state != BOUND) { if (ctrlc()) { ret = -EINTR; goto out1; } if (!retries) { ret = -ETIMEDOUT; goto out1; } net_poll(); if (is_timeout(dhcp_start, 3 * SECOND)) { dhcp_start = get_time_ns(); printf("T "); ret = bootp_request(); /* no need to check if retries > 0 as we check if != 0 */ retries--; if (ret) goto out1; } } if (dhcp_tftpname[0] != 0) { IPaddr_t tftpserver = resolv(dhcp_tftpname); if (tftpserver) net_set_serverip(tftpserver); } out1: net_unregister(dhcp_con); out: if (ret) debug("dhcp failed: %s\n", strerror(-ret)); return ret; }
static int serial(int argc, char ** argv) { struct chrdev * device = NULL; ssize_t (* read_func)(struct chrdev *, u8_t *, size_t); struct serial_parameter param; char * name = NULL, * str = NULL; char * baud = 0; char * data_bit = 0; char * parity = 0; char * stop_bit = 0; u8_t c; s32_t i; if(argc < 2) { serial_info(); return 0; } if( !strcmp((const char *)argv[1],"info") ) { serial_info(); } else if( !strcmp((const char *)argv[1],"send") ) { if(argc != 4) { printk("usage:\r\n serial [info]\r\n" " serial send <DEVICE NAME> <STRING>\r\n" " serial recv <DEVICE NAME>\r\n" " serial param <DEVICE NAME> [-b BAUD] [-d DATABITS] [-p PARITY] [-s STOPBITS]\r\n"); return (-1); } name = (char *)argv[2]; str = (char *)argv[3]; device = search_chrdev_with_type((const char *)name, CHR_DEV_SERIAL); if(!device) { printk(" not found serial device \"%s\"\r\n", name); printk(" try 'serial info' for list all of serial devices\r\n"); return -1; } if(device->open) (device->open)(device); if(device->write) (device->write)(device, (u8_t *)str, strlen(str)); if(device->close) (device->close)(device); } else if( !strcmp((const char *)argv[1],"recv") ) { if(argc != 3) { printk("usage:\r\n serial [info]\r\n" " serial send <DEVICE NAME> <STRING>\r\n" " serial recv <DEVICE NAME>\r\n" " serial param <DEVICE NAME> [-b BAUD] [-d DATABITS] [-p PARITY] [-s STOPBITS]\r\n"); return (-1); } name = (char *)argv[2]; device = search_chrdev_with_type((const char *)name, CHR_DEV_SERIAL); if(!device) { printk(" not found serial device \"%s\"\r\n", name); printk(" try 'serial info' for list all of serial devices\r\n"); return -1; } if(device->open) (device->open)(device); if(device->read) { read_func = device->read; while(1) { if(read_func(device, &c, 1) == 1) { if(isprint(c) || isspace(c)) printk("%c", c); else printk("<%02x>", c); } if(ctrlc()) break; } } if(device->close) (device->close)(device); } else if( !strcmp((const char *)argv[1],"param") ) { if(argc < 3) { printk("usage:\r\n serial [info]\r\n" " serial send <DEVICE NAME> <STRING>\r\n" " serial recv <DEVICE NAME>\r\n" " serial param <DEVICE NAME> [-b BAUD] [-d DATABITS] [-p PARITY] [-s STOPBITS]\r\n"); return (-1); } for(i=2; i<argc; i++) { if( !strcmp((const char *)argv[i],"-b") && (argc > i+1)) { baud = (char *)argv[i+1]; i++; } else if( !strcmp((const char *)argv[i],"-d") && (argc > i+1)) { data_bit = (char *)argv[i+1]; i++; } else if( !strcmp((const char *)argv[i],"-p") && (argc > i+1)) { parity = (char *)argv[i+1]; i++; } else if( !strcmp((const char *)argv[i],"-s") && (argc > i+1)) { stop_bit = (char *)argv[i+1]; i++; } else if(*argv[i] != '-' && strcmp((const char *)argv[i], "-") != 0) { name = (char *)argv[i]; device = search_chrdev_with_type((const char *)name, CHR_DEV_SERIAL); if(!device) { printk(" not found serial device \"%s\"\r\n", name); printk(" try 'serial info' for list all of serial devices\r\n"); return -1; } if(!(device->ioctl)) { printk(" don't support ioctl function at this device.\r\n"); return -1; } } } if(!name) { printk("usage:\r\n serial [info]\r\n" " serial send <DEVICE NAME> <STRING>\r\n" " serial recv <DEVICE NAME>\r\n" " serial param <DEVICE NAME> [-b BAUD] [-d DATABITS] [-p PARITY] [-s STOPBITS]\r\n"); return (-1); } if(baud) { if(!strcmp(baud, "50")) param.baud_rate = B50; else if(!strcmp(baud, "75")) param.baud_rate = B75; else if(!strcmp(baud, "110")) param.baud_rate = B110; else if(!strcmp(baud, "134")) param.baud_rate = B134; else if(!strcmp(baud, "200")) param.baud_rate = B200; else if(!strcmp(baud, "300")) param.baud_rate = B300; else if(!strcmp(baud, "600")) param.baud_rate = B600; else if(!strcmp(baud, "1200")) param.baud_rate = B1200; else if(!strcmp(baud, "1800")) param.baud_rate = B1800; else if(!strcmp(baud, "2400")) param.baud_rate = B2400; else if(!strcmp(baud, "4800")) param.baud_rate = B4800; else if(!strcmp(baud, "9600")) param.baud_rate = B9600; else if(!strcmp(baud, "19200")) param.baud_rate = B19200; else if(!strcmp(baud, "38400")) param.baud_rate = B38400; else if(!strcmp(baud, "57600")) param.baud_rate = B57600; else if(!strcmp(baud, "76800")) param.baud_rate = B76800; else if(!strcmp(baud, "115200")) param.baud_rate = B115200; else if(!strcmp(baud, "230400")) param.baud_rate = B230400; else if(!strcmp(baud, "380400")) param.baud_rate = B380400; else if(!strcmp(baud, "460800")) param.baud_rate = B460800; else if(!strcmp(baud, "921600")) param.baud_rate = B921600; else { printk("unrecognize the parameter of baud rate \"%s\"\r\n", baud); return -1; } if(device->ioctl(device, IOCTL_WR_SERIAL_BAUD_RATE, (void *)(&(param.baud_rate))) < 0) { printk("setting serial device's baud rate fail. (%s)\r\n", device->name); return -1; } } if(data_bit) { if(!strcmp(data_bit, "5")) param.data_bit = DATA_BITS_5; else if(!strcmp(data_bit, "6")) param.data_bit = DATA_BITS_6; else if(!strcmp(data_bit, "7")) param.data_bit = DATA_BITS_7; else if(!strcmp(data_bit, "8")) param.data_bit = DATA_BITS_8; else { printk("unrecognize the parameter of data bits \"%s\"\r\n", data_bit); return -1; } if(device->ioctl(device, IOCTL_WR_SERIAL_DATA_BITS, (void *)(&(param.data_bit))) < 0) { printk("setting serial device's data bits fail. (%s)\r\n", device->name); return -1; } } if(parity) { if(!strcmp(parity, "N")) param.parity = PARITY_NONE; else if(!strcmp(parity, "E")) param.parity = PARITY_EVEN; else if(!strcmp(parity, "O")) param.parity = PARITY_ODD; else { printk("unrecognize the parameter of parity \"%s\"\r\n", parity); return -1; } if(device->ioctl(device, IOCTL_WR_SERIAL_PARITY_BIT, (void *)(&(param.parity))) < 0) { printk("setting serial device's parity fail. (%s)\r\n", device->name); return -1; } } if(stop_bit) { if(!strcmp(stop_bit, "1")) param.stop_bit = STOP_BITS_1; else if(!strcmp(stop_bit, "1.5")) param.stop_bit = STOP_BITS_1_5; else if(!strcmp(stop_bit, "2")) param.stop_bit = STOP_BITS_2; else { printk("unrecognize the parameter of stop bits \"%s\"\r\n", stop_bit); return -1; } if(device->ioctl(device, IOCTL_WR_SERIAL_STOP_BITS, (void *)(&(param.stop_bit))) < 0) { printk("setting serial device's stop bit fail. (%s)\r\n", device->name); return -1; } } printk("setting serial device's parameter successed. (%s)\r\n", device->name); return 0; } else { printk("serial: invalid option '%s'\r\n", argv[1]); printk("usage:\r\n serial [info]\r\n" " serial send <DEVICE NAME> <STRING>\r\n" " serial recv <DEVICE NAME>\r\n" " serial param <DEVICE NAME> [-b BAUD] [-d DATABITS] [-p PARITY] [-s STOPBITS]\r\n"); printk("try 'help serial' for more information.\r\n"); return (-1); } return 0; }
int do_caddy(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned long base_addr; uint32_t ptr; struct caddy_cmd *caddy_cmd; uint32_t result[5]; uint16_t data16; uint8_t data8; uint32_t status; pci_dev_t dev; void *pci_ptr; if (argc < 2) { puts("Missing parameter\n"); return 1; } base_addr = simple_strtoul(argv[1], NULL, 16); caddy_interface = (struct caddy_interface *) base_addr; memset((void *)caddy_interface, 0, sizeof(struct caddy_interface)); memcpy((void *)&caddy_interface->magic[0], &CADDY_MAGIC, 16); while (ctrlc() == 0) { if (caddy_interface->cmd_in != caddy_interface->cmd_out) { memset(result, 0, 5 * sizeof(result[0])); status = 0; caddy_cmd = &caddy_interface->cmd[caddy_interface->cmd_out]; pci_ptr = (void *)CONFIG_SYS_PCI1_IO_PHYS + (caddy_cmd->addr & 0x001fffff); switch (caddy_cmd->cmd) { case CADDY_CMD_IO_READ_8: result[0] = in_8(pci_ptr); break; case CADDY_CMD_IO_READ_16: result[0] = in_be16(pci_ptr); break; case CADDY_CMD_IO_READ_32: result[0] = in_be32(pci_ptr); break; case CADDY_CMD_IO_WRITE_8: data8 = caddy_cmd->par[0] & 0x000000ff; out_8(pci_ptr, data8); break; case CADDY_CMD_IO_WRITE_16: data16 = caddy_cmd->par[0] & 0x0000ffff; out_be16(pci_ptr, data16); break; case CADDY_CMD_IO_WRITE_32: out_be32(pci_ptr, caddy_cmd->par[0]); break; case CADDY_CMD_CONFIG_READ_8: dev = PCI_BDF(caddy_cmd->par[0], caddy_cmd->par[1], caddy_cmd->par[2]); status = pci_read_config_byte(dev, caddy_cmd->addr, &data8); result[0] = data8; break; case CADDY_CMD_CONFIG_READ_16: dev = PCI_BDF(caddy_cmd->par[0], caddy_cmd->par[1], caddy_cmd->par[2]); status = pci_read_config_word(dev, caddy_cmd->addr, &data16); result[0] = data16; break; case CADDY_CMD_CONFIG_READ_32: dev = PCI_BDF(caddy_cmd->par[0], caddy_cmd->par[1], caddy_cmd->par[2]); status = pci_read_config_dword(dev, caddy_cmd->addr, &result[0]); break; case CADDY_CMD_CONFIG_WRITE_8: dev = PCI_BDF(caddy_cmd->par[0], caddy_cmd->par[1], caddy_cmd->par[2]); data8 = caddy_cmd->par[3] & 0x000000ff; status = pci_write_config_byte(dev, caddy_cmd->addr, data8); break; case CADDY_CMD_CONFIG_WRITE_16: dev = PCI_BDF(caddy_cmd->par[0], caddy_cmd->par[1], caddy_cmd->par[2]); data16 = caddy_cmd->par[3] & 0x0000ffff; status = pci_write_config_word(dev, caddy_cmd->addr, data16); break; case CADDY_CMD_CONFIG_WRITE_32: dev = PCI_BDF(caddy_cmd->par[0], caddy_cmd->par[1], caddy_cmd->par[2]); status = pci_write_config_dword(dev, caddy_cmd->addr, caddy_cmd->par[3]); break; default: status = 0xffffffff; break; } generate_answer(caddy_cmd, status, &result[0]); ptr = caddy_interface->cmd_out + 1; ptr = ptr & (CMD_SIZE - 1); caddy_interface->cmd_out = ptr; } caddy_interface->heartbeat++; } return 0; }
int NetLoop(enum proto_t protocol) { bd_t *bd = gd->bd; int ret = -1; NetRestarted = 0; NetDevExists = 0; NetTryCount = 1; debug_cond(DEBUG_INT_STATE, "--- NetLoop Entry\n"); bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start"); net_init(); if (eth_is_on_demand_init() || protocol != NETCONS) { eth_halt(); eth_set_current(); if (eth_init(bd) < 0) { eth_halt(); return -1; } } else eth_init_state_only(bd); restart: net_set_state(NETLOOP_CONTINUE); /* * Start the ball rolling with the given start function. From * here on, this code is a state machine driven by received * packets and timer events. */ debug_cond(DEBUG_INT_STATE, "--- NetLoop Init\n"); NetInitLoop(); switch (net_check_prereq(protocol)) { case 1: /* network not configured */ eth_halt(); return -1; case 2: /* network device not configured */ break; case 0: NetDevExists = 1; NetBootFileXferSize = 0; switch (protocol) { case TFTPGET: #ifdef CONFIG_CMD_TFTPPUT case TFTPPUT: #endif /* always use ARP to get server ethernet address */ TftpStart(protocol); break; #ifdef CONFIG_CMD_TFTPSRV case TFTPSRV: TftpStartServer(); break; #endif #if defined(CONFIG_CMD_DHCP) case DHCP: BootpTry = 0; NetOurIP = 0; DhcpRequest(); /* Basically same as BOOTP */ break; #endif case BOOTP: BootpTry = 0; NetOurIP = 0; BootpRequest(); break; #if defined(CONFIG_CMD_RARP) case RARP: RarpTry = 0; NetOurIP = 0; RarpRequest(); break; #endif #if defined(CONFIG_CMD_PING) case PING: ping_start(); break; #endif #if defined(CONFIG_CMD_NFS) case NFS: NfsStart(); break; #endif #if defined(CONFIG_CMD_CDP) case CDP: CDPStart(); break; #endif #ifdef CONFIG_NETCONSOLE case NETCONS: NcStart(); break; #endif #if defined(CONFIG_CMD_SNTP) case SNTP: SntpStart(); break; #endif #if defined(CONFIG_CMD_DNS) case DNS: DnsStart(); break; #endif #if defined(CONFIG_CMD_LINK_LOCAL) case LINKLOCAL: link_local_start(); break; #endif #if defined(CONFIG_CMD_BOOTCE) case BOOTME: BootmeStart(); break; #endif default: break; } break; } #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \ defined(CONFIG_STATUS_LED) && \ defined(STATUS_LED_RED) /* * Echo the inverted link state to the fault LED. */ if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR)) status_led_set(STATUS_LED_RED, STATUS_LED_OFF); else status_led_set(STATUS_LED_RED, STATUS_LED_ON); #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ #endif /* CONFIG_MII, ... */ /* * Main packet reception loop. Loop receiving packets until * someone sets `net_state' to a state that terminates. */ for (;;) { WATCHDOG_RESET(); #ifdef CONFIG_SHOW_ACTIVITY show_activity(1); #endif /* * Check the ethernet for a new packet. The ethernet * receive routine will process it. */ eth_rx(); /* * Abort if ctrl-c was pressed. */ if (ctrlc()) { /* cancel any ARP that may not have completed */ NetArpWaitPacketIP = 0; net_cleanup_loop(); eth_halt(); /* Invalidate the last protocol */ eth_set_last_protocol(BOOTP); puts("\nAbort\n"); /* include a debug print as well incase the debug messages are directed to stderr */ debug_cond(DEBUG_INT_STATE, "--- NetLoop Abort!\n"); goto done; } ArpTimeoutCheck(); /* * Check for a timeout, and run the timeout handler * if we have one. */ if (timeHandler && ((get_timer(timeStart)) > timeDelta)) { thand_f *x; #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) && \ defined(CONFIG_STATUS_LED) && \ defined(STATUS_LED_RED) /* * Echo the inverted link state to the fault LED. */ if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR)) { status_led_set(STATUS_LED_RED, STATUS_LED_OFF); } else { status_led_set(STATUS_LED_RED, STATUS_LED_ON); } #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ #endif /* CONFIG_MII, ... */ debug_cond(DEBUG_INT_STATE, "--- NetLoop timeout\n"); x = timeHandler; timeHandler = (thand_f *)0; (*x)(); } switch (net_state) { case NETLOOP_RESTART: NetRestarted = 1; goto restart; case NETLOOP_SUCCESS: net_cleanup_loop(); if (NetBootFileXferSize > 0) { char buf[20]; printf("Bytes transferred = %ld (%lx hex)\n", NetBootFileXferSize, NetBootFileXferSize); sprintf(buf, "%lX", NetBootFileXferSize); setenv("filesize", buf); sprintf(buf, "%lX", (unsigned long)load_addr); setenv("fileaddr", buf); } if (protocol != NETCONS) { eth_halt(); } else { eth_halt_state_only(); } eth_set_last_protocol(protocol); ret = NetBootFileXferSize; debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!\n"); goto done; case NETLOOP_FAIL: net_cleanup_loop(); /* Invalidate the last protocol */ eth_set_last_protocol(BOOTP); debug_cond(DEBUG_INT_STATE, "--- NetLoop Fail!\n"); goto done; case NETLOOP_CONTINUE: continue; } } done: #ifdef CONFIG_CMD_TFTPPUT /* Clear out the handlers */ net_set_udp_handler(NULL); net_set_icmp_handler(NULL); #endif return ret; }
/* * Perform a memory test. A more complete alternative test can be * configured using CFG_ALT_MEMTEST. The complete test loops until * interrupted by ctrl-c or by a failure of one of the sub-tests. */ int do_mem_mtest (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { vu_long *addr, *start, *end; ulong val; ulong readback; #if defined(CFG_ALT_MEMTEST) vu_long addr_mask; vu_long offset; vu_long test_offset; vu_long pattern; vu_long temp; vu_long anti_pattern; vu_long num_words; #if defined(CFG_MEMTEST_SCRATCH) vu_long *dummy = (vu_long*)CFG_MEMTEST_SCRATCH; #else vu_long *dummy = NULL; #endif int j; int iterations = 1; static const ulong bitpattern[] = { 0x00000001, /* single bit */ 0x00000003, /* two adjacent bits */ 0x00000007, /* three adjacent bits */ 0x0000000F, /* four adjacent bits */ 0x00000005, /* two non-adjacent bits */ 0x00000015, /* three non-adjacent bits */ 0x00000055, /* four non-adjacent bits */ 0xaaaaaaaa, /* alternating 1/0 */ }; #else ulong incr; ulong pattern; int rcode = 0; #endif if (argc > 1) { start = (ulong *)simple_strtoul(argv[1], NULL, 16); } else { start = (ulong *)CFG_MEMTEST_START; } if (argc > 2) { end = (ulong *)simple_strtoul(argv[2], NULL, 16); } else { end = (ulong *)(CFG_MEMTEST_END); } if (argc > 3) { pattern = (ulong)simple_strtoul(argv[3], NULL, 16); } else { pattern = 0; } #if defined(CFG_ALT_MEMTEST) printf ("Testing %08x ... %08x:\n", (uint)start, (uint)end); PRINTF("%s:%d: start 0x%p end 0x%p\n", __FUNCTION__, __LINE__, start, end); for (;;) { if (ctrlc()) { putc ('\n'); return 1; } printf("Iteration: %6d\r", iterations); PRINTF("Iteration: %6d\n", iterations); iterations++; /* * Data line test: write a pattern to the first * location, write the 1's complement to a 'parking' * address (changes the state of the data bus so a * floating bus doen't give a false OK), and then * read the value back. Note that we read it back * into a variable because the next time we read it, * it might be right (been there, tough to explain to * the quality guys why it prints a failure when the * "is" and "should be" are obviously the same in the * error message). * * Rather than exhaustively testing, we test some * patterns by shifting '1' bits through a field of * '0's and '0' bits through a field of '1's (i.e. * pattern and ~pattern). */ addr = start; for (j = 0; j < sizeof(bitpattern)/sizeof(bitpattern[0]); j++) { val = bitpattern[j]; for(; val != 0; val <<= 1) { *addr = val; *dummy = ~val; /* clear the test data off of the bus */ readback = *addr; if(readback != val) { printf ("FAILURE (data line): " "expected %08lx, actual %08lx\n", val, readback); } *addr = ~val; *dummy = val; readback = *addr; if(readback != ~val) { printf ("FAILURE (data line): " "Is %08lx, should be %08lx\n", readback, ~val); } } } /* * Based on code whose Original Author and Copyright * information follows: Copyright (c) 1998 by Michael * Barr. This software is placed into the public * domain and may be used for any purpose. However, * this notice must not be changed or removed and no * warranty is either expressed or implied by its * publication or distribution. */ /* * Address line test * * Description: Test the address bus wiring in a * memory region by performing a walking * 1's test on the relevant bits of the * address and checking for aliasing. * This test will find single-bit * address failures such as stuck -high, * stuck-low, and shorted pins. The base * address and size of the region are * selected by the caller. * * Notes: For best results, the selected base * address should have enough LSB 0's to * guarantee single address bit changes. * For example, to test a 64-Kbyte * region, select a base address on a * 64-Kbyte boundary. Also, select the * region size as a power-of-two if at * all possible. * * Returns: 0 if the test succeeds, 1 if the test fails. * * ## NOTE ## Be sure to specify start and end * addresses such that addr_mask has * lots of bits set. For example an * address range of 01000000 02000000 is * bad while a range of 01000000 * 01ffffff is perfect. */ addr_mask = ((ulong)end - (ulong)start)/sizeof(vu_long); pattern = (vu_long) 0xaaaaaaaa; anti_pattern = (vu_long) 0x55555555; PRINTF("%s:%d: addr mask = 0x%.8lx\n", __FUNCTION__, __LINE__, addr_mask); /* * Write the default pattern at each of the * power-of-two offsets. */ for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) { start[offset] = pattern; } /* * Check for address bits stuck high. */ test_offset = 0; start[test_offset] = anti_pattern; for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) { temp = start[offset]; if (temp != pattern) { printf ("\nFAILURE: Address bit stuck high @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx\n", (ulong)&start[offset], pattern, temp); return 1; } } start[test_offset] = pattern; /* * Check for addr bits stuck low or shorted. */ for (test_offset = 1; (test_offset & addr_mask) != 0; test_offset <<= 1) { start[test_offset] = anti_pattern; for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) { temp = start[offset]; if ((temp != pattern) && (offset != test_offset)) { printf ("\nFAILURE: Address bit stuck low or shorted @" " 0x%.8lx: expected 0x%.8lx, actual 0x%.8lx\n", (ulong)&start[offset], pattern, temp); return 1; } } start[test_offset] = pattern; } /* * Description: Test the integrity of a physical * memory device by performing an * increment/decrement test over the * entire region. In the process every * storage bit in the device is tested * as a zero and a one. The base address * and the size of the region are * selected by the caller. * * Returns: 0 if the test succeeds, 1 if the test fails. */ num_words = ((ulong)end - (ulong)start)/sizeof(vu_long) + 1; /* * Fill memory with a known pattern. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { start[offset] = pattern; } /* * Check each location and invert it for the second pass. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { temp = start[offset]; if (temp != pattern) { printf ("\nFAILURE (read/write) @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx)\n", (ulong)&start[offset], pattern, temp); return 1; } anti_pattern = ~pattern; start[offset] = anti_pattern; } /* * Check each location for the inverted pattern and zero it. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { anti_pattern = ~pattern; temp = start[offset]; if (temp != anti_pattern) { printf ("\nFAILURE (read/write): @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx)\n", (ulong)&start[offset], anti_pattern, temp); return 1; } start[offset] = 0; } } #else /* The original, quickie test */ incr = 1; for (;;) { if (ctrlc()) { putc ('\n'); return 1; } printf ("\rPattern %08lX Writing..." "%12s" "\b\b\b\b\b\b\b\b\b\b", pattern, ""); for (addr=start,val=pattern; addr<end; addr++) { *addr = val; val += incr; } puts ("Reading..."); for (addr=start,val=pattern; addr<end; addr++) { readback = *addr; if (readback != val) { printf ("\nMem error @ 0x%08X: " "found %08lX, expected %08lX\n", (uint)addr, readback, val); rcode = 1; } val += incr; } /* * Flip the pattern each time to make lots of zeros and * then, the next time, lots of ones. We decrement * the "negative" patterns and increment the "positive" * patterns to preserve this feature. */ if(pattern & 0x80000000) { pattern = -pattern; /* complement & increment */ } else { pattern = ~pattern; } incr = -incr; } return rcode; #endif }
void idma_start (int sinc, int dinc, int sz, uint sbuf, uint dbuf, int ttype) { /* ttype is for M-M, M-P, P-M or P-P: not used for now */ piptr->pi_istate = 0; /* manual says: clear it before every START_IDMA */ piptr->pi_dcmbits.b.b_resv1 = 0; if (sinc == 1) piptr->pi_dcmbits.b.b_sinc = 1; else piptr->pi_dcmbits.b.b_sinc = 0; if (dinc == 1) piptr->pi_dcmbits.b.b_dinc = 1; else piptr->pi_dcmbits.b.b_dinc = 0; piptr->pi_dcmbits.b.b_erm = 0; piptr->pi_dcmbits.b.b_sd = 0x00; /* M-M */ bdf->ibd_sbuf = sbuf; bdf->ibd_dbuf = dbuf; bdf->ibd_bits.b.b_cm = 0; bdf->ibd_bits.b.b_interrupt = 1; bdf->ibd_bits.b.b_wrap = 1; bdf->ibd_bits.b.b_last = 1; bdf->ibd_bits.b.b_sdn = 0; bdf->ibd_bits.b.b_ddn = 0; bdf->ibd_bits.b.b_dgbl = 0; bdf->ibd_bits.b.b_ddtb = 0; bdf->ibd_bits.b.b_sgbl = 0; bdf->ibd_bits.b.b_sdtb = 0; bdf->ibd_bits.b.b_dbo = 1; bdf->ibd_bits.b.b_sbo = 1; bdf->ibd_bits.b.b_valid = 1; bdf->ibd_datlen = 512; *dmadonep = 0; immap->im_sdma.sdma_idmr2 = (uchar) 0xf; immap->im_cpm.cp_cpcr = mk_cr_cmd (CPM_CR_IDMA2_PAGE, CPM_CR_IDMA2_SBLOCK, 0x0, 0x9) | 0x00010000; while (*dmadonep != 1) { if (ctrlc ()) { DEBUG ("\nInterrupted waiting for DMA interrupt.\n"); goto done; } printf ("Waiting for DMA interrupt (dmadone=%d b_valid = %d)...\n", dmadone, bdf->ibd_bits.b.b_valid); udelay (1000000); } printf ("DMA complete notification received!\n"); done: DEBUG ("memcmp(0x%08x, 0x%08x, 512) = %d\n", sbuf, dbuf, memcmp ((void *) sbuf, (void *) dbuf, 512)); return; }
static int mem_test(ulong _start, ulong _end, ulong pattern_unused) { vu_long *start = (vu_long *)_start; vu_long *end = (vu_long *)_end; vu_long *addr; ulong val; ulong readback; vu_long addr_mask; vu_long offset; vu_long test_offset; vu_long pattern; vu_long temp; vu_long anti_pattern; vu_long num_words; #ifdef CFG_MEMTEST_SCRATCH vu_long *dummy = (vu_long*)CFG_MEMTEST_SCRATCH; #else vu_long *dummy = start; #endif int j; int iterations = 1; static const ulong bitpattern[] = { 0x00000001, /* single bit */ 0x00000003, /* two adjacent bits */ 0x00000007, /* three adjacent bits */ 0x0000000F, /* four adjacent bits */ 0x00000005, /* two non-adjacent bits */ 0x00000015, /* three non-adjacent bits */ 0x00000055, /* four non-adjacent bits */ 0xaaaaaaaa, /* alternating 1/0 */ }; /* XXX: enforce alignment of start and end? */ for (;;) { if (ctrlc()) { putchar ('\n'); return 1; } printf("Iteration: %6d\r", iterations); iterations++; /* * Data line test: write a pattern to the first * location, write the 1's complement to a 'parking' * address (changes the state of the data bus so a * floating bus doen't give a false OK), and then * read the value back. Note that we read it back * into a variable because the next time we read it, * it might be right (been there, tough to explain to * the quality guys why it prints a failure when the * "is" and "should be" are obviously the same in the * error message). * * Rather than exhaustively testing, we test some * patterns by shifting '1' bits through a field of * '0's and '0' bits through a field of '1's (i.e. * pattern and ~pattern). */ addr = start; /* XXX */ if (addr == dummy) ++addr; for (j = 0; j < sizeof(bitpattern)/sizeof(bitpattern[0]); j++) { val = bitpattern[j]; for(; val != 0; val <<= 1) { *addr = val; *dummy = ~val; /* clear the test data off of the bus */ readback = *addr; if(readback != val) { printf ("FAILURE (data line): " "expected 0x%08lx, actual 0x%08lx at address 0x%p\n", val, readback, addr); } *addr = ~val; *dummy = val; readback = *addr; if(readback != ~val) { printf ("FAILURE (data line): " "Is 0x%08lx, should be 0x%08lx at address 0x%p\n", readback, ~val, addr); } } } /* * Based on code whose Original Author and Copyright * information follows: Copyright (c) 1998 by Michael * Barr. This software is placed into the public * domain and may be used for any purpose. However, * this notice must not be changed or removed and no * warranty is either expressed or implied by its * publication or distribution. */ /* * Address line test * * Description: Test the address bus wiring in a * memory region by performing a walking * 1's test on the relevant bits of the * address and checking for aliasing. * This test will find single-bit * address failures such as stuck -high, * stuck-low, and shorted pins. The base * address and size of the region are * selected by the caller. * * Notes: For best results, the selected base * address should have enough LSB 0's to * guarantee single address bit changes. * For example, to test a 64-Kbyte * region, select a base address on a * 64-Kbyte boundary. Also, select the * region size as a power-of-two if at * all possible. * * Returns: 0 if the test succeeds, 1 if the test fails. * * ## NOTE ## Be sure to specify start and end * addresses such that addr_mask has * lots of bits set. For example an * address range of 01000000 02000000 is * bad while a range of 01000000 * 01ffffff is perfect. */ addr_mask = ((ulong)end - (ulong)start)/sizeof(vu_long); pattern = (vu_long) 0xaaaaaaaa; anti_pattern = (vu_long) 0x55555555; debug("%s:%d: addr mask = 0x%.8lx\n", __FUNCTION__, __LINE__, addr_mask); /* * Write the default pattern at each of the * power-of-two offsets. */ for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) start[offset] = pattern; /* * Check for address bits stuck high. */ test_offset = 0; start[test_offset] = anti_pattern; for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) { temp = start[offset]; if (temp != pattern) { printf ("\nFAILURE: Address bit stuck high @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx\n", (ulong)&start[offset], pattern, temp); return 1; } } start[test_offset] = pattern; /* * Check for addr bits stuck low or shorted. */ for (test_offset = 1; (test_offset & addr_mask) != 0; test_offset <<= 1) { start[test_offset] = anti_pattern; for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) { temp = start[offset]; if ((temp != pattern) && (offset != test_offset)) { printf ("\nFAILURE: Address bit stuck low or shorted @" " 0x%.8lx: expected 0x%.8lx, actual 0x%.8lx\n", (ulong)&start[offset], pattern, temp); return 1; } } start[test_offset] = pattern; } /* * Description: Test the integrity of a physical * memory device by performing an * increment/decrement test over the * entire region. In the process every * storage bit in the device is tested * as a zero and a one. The base address * and the size of the region are * selected by the caller. * * Returns: 0 if the test succeeds, 1 if the test fails. */ num_words = ((ulong)end - (ulong)start)/sizeof(vu_long) + 1; /* * Fill memory with a known pattern. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { start[offset] = pattern; } /* * Check each location and invert it for the second pass. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { temp = start[offset]; if (temp != pattern) { printf ("\nFAILURE (read/write) @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx)\n", (ulong)&start[offset], pattern, temp); return 1; } anti_pattern = ~pattern; start[offset] = anti_pattern; } /* * Check each location for the inverted pattern and zero it. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { anti_pattern = ~pattern; temp = start[offset]; if (temp != anti_pattern) { printf ("\nFAILURE (read/write): @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx)\n", (ulong)&start[offset], anti_pattern, temp); return 1; } start[offset] = 0; } } }
int flash_erase (flash_info_t *info, int s_first, int s_last) { int iflag, cflag, prot, sect; int rc = ERR_OK; /* first look for protection bits */ if (info->flash_id == FLASH_UNKNOWN) return ERR_UNKNOWN_FLASH_TYPE; if ((s_first < 0) || (s_first > s_last)) return ERR_INVAL; if ((info->flash_id & FLASH_VENDMASK) != (FLASH_MAN_MT & FLASH_VENDMASK)) return ERR_UNKNOWN_FLASH_VENDOR; prot = 0; for (sect = s_first; sect <= s_last; ++sect) { if (info->protect[sect]) prot++; } if (prot) { printf("protected!\n"); return ERR_PROTECTED; } /* * Disable interrupts which might cause a timeout * here. Remember that our exception vectors are * at address 0 in the flash, and we don't want a * (ticker) exception to happen while the flash * chip is in programming mode. */ cflag = icache_status(); icache_disable(); iflag = disable_interrupts(); /* Start erase on unprotected sectors */ for (sect = s_first; sect <= s_last && !ctrlc(); sect++) { printf("Erasing sector %2d ... ", sect); /* arm simple, non interrupt dependent timer */ get_timer(0); SF_NvmodeErase(); SF_NvmodeWrite(); SF_Erase(CONFIG_SYS_FLASH_BASE + (0x0100000 * sect)); SF_Normal(); printf("ok.\n"); } if (ctrlc()) printf("User Interrupt!\n"); if (iflag) enable_interrupts(); if (cflag) icache_enable(); return rc; }
static int ACEX1K_ps_load(Altera_desc *desc, const void *buf, size_t bsize) { int ret_val = FPGA_FAIL; /* assume the worst */ Altera_ACEX1K_Passive_Serial_fns *fn = desc->iface_fns; int i; PRINTF ("%s: start with interface functions @ 0x%p\n", __FUNCTION__, fn); if (fn) { size_t bytecount = 0; unsigned char *data = (unsigned char *) buf; int cookie = desc->cookie; /* make a local copy */ unsigned long ts; /* timestamp */ PRINTF ("%s: Function Table:\n" "ptr:\t0x%p\n" "struct: 0x%p\n" "config:\t0x%p\n" "status:\t0x%p\n" "clk:\t0x%p\n" "data:\t0x%p\n" "done:\t0x%p\n\n", __FUNCTION__, &fn, fn, fn->config, fn->status, fn->clk, fn->data, fn->done); #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK printf ("Loading FPGA Device %d...", cookie); #endif /* * Run the pre configuration function if there is one. */ if (*fn->pre) { (*fn->pre) (cookie); } /* Establish the initial state */ (*fn->config) (true, true, cookie); /* Assert nCONFIG */ udelay(2); /* T_cfg > 2us */ /* nSTATUS should be asserted now */ (*fn->done) (cookie); if ( !(*fn->status) (cookie) ) { puts ("** nSTATUS is not asserted.\n"); (*fn->abort) (cookie); return FPGA_FAIL; } (*fn->config) (false, true, cookie); /* Deassert nCONFIG */ udelay(2); /* T_cf2st1 < 4us */ /* Wait for nSTATUS to be released (i.e. deasserted) */ ts = get_timer (0); /* get current time */ do { CONFIG_FPGA_DELAY (); if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ puts ("** Timeout waiting for STATUS to go high.\n"); (*fn->abort) (cookie); return FPGA_FAIL; } (*fn->done) (cookie); } while ((*fn->status) (cookie)); /* Get ready for the burn */ CONFIG_FPGA_DELAY (); /* Load the data */ while (bytecount < bsize) { unsigned char val=0; #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC if (ctrlc ()) { (*fn->abort) (cookie); return FPGA_FAIL; } #endif /* Altera detects an error if INIT goes low (active) while DONE is low (inactive) */ #if 0 /* not yet implemented */ if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) { puts ("** CRC error during FPGA load.\n"); (*fn->abort) (cookie); return (FPGA_FAIL); } #endif val = data [bytecount ++ ]; i = 8; do { /* Deassert the clock */ (*fn->clk) (false, true, cookie); CONFIG_FPGA_DELAY (); /* Write data */ (*fn->data) ((val & 0x01), true, cookie); CONFIG_FPGA_DELAY (); /* Assert the clock */ (*fn->clk) (true, true, cookie); CONFIG_FPGA_DELAY (); val >>= 1; i --; } while (i > 0); #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK if (bytecount % (bsize / 40) == 0) putc ('.'); /* let them know we are alive */ #endif } CONFIG_FPGA_DELAY (); #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK putc (' '); /* terminate the dotted line */ #endif /* * Checking FPGA's CONF_DONE signal - correctly booted ? */ if ( ! (*fn->done) (cookie) ) { puts ("** Booting failed! CONF_DONE is still deasserted.\n"); (*fn->abort) (cookie); return (FPGA_FAIL); } /* * "DCLK must be clocked an additional 10 times fpr ACEX 1K..." */ for (i = 0; i < 12; i++) { CONFIG_FPGA_DELAY (); (*fn->clk) (true, true, cookie); /* Assert the clock pin */ CONFIG_FPGA_DELAY (); (*fn->clk) (false, true, cookie); /* Deassert the clock pin */ } ret_val = FPGA_SUCCESS; #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK if (ret_val == FPGA_SUCCESS) { puts ("Done.\n"); } else { puts ("Fail.\n"); } #endif (*fn->post) (cookie); } else {
int do_loadpci (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { char *s; ulong addr = 0, count = 0; u32 off; int cmd, rcode = 0; /* pre-set load_addr */ if ((s = getenv("loadaddr")) != NULL) { addr = simple_strtoul(s, NULL, 16); } switch (argc) { case 1: break; case 2: addr = simple_strtoul(argv[1], NULL, 16); break; default: printf ("Usage:\n%s\n", cmdtp->usage); return 1; } printf ("## Ready for image download ...\n"); show_startup_phase(12); while (1) { /* Alive indicator */ i2155x_write_scrapad(BOOT_PROTO, BOOT_PROTO_READY); /* Toggle status LEDs */ cmd = (count / 200) % 4; /* downscale */ set_led(4, cmd == 0 ? LED_1 : LED_0); set_led(5, cmd == 1 ? LED_1 : LED_0); set_led(6, cmd == 2 ? LED_1 : LED_0); set_led(7, cmd == 3 ? LED_1 : LED_0); udelay(1000); count++; cmd = i2155x_read_scrapad(BOOT_CMD); if (cmd == BOOT_CMD_MOVE) { off = i2155x_read_scrapad(BOOT_DATA); off += addr; i2155x_set_bar_base(3, off); printf ("## BAR3 Addr moved = 0x%08x\n", off); i2155x_write_scrapad(BOOT_CMD, ~cmd); show_startup_phase(13); } else if (cmd == BOOT_CMD_BOOT) { set_led(4, LED_1); set_led(5, LED_1); set_led(6, LED_1); set_led(7, LED_1); i2155x_write_scrapad(BOOT_CMD, ~cmd); show_startup_phase(14); break; } /* Abort if ctrl-c was pressed */ if (ctrlc()) { printf("\nAbort\n"); return 0; } } /* Repoint to the default shared memory */ i2155x_set_bar_base(3, PN62_SMEM_DEFAULT); load_addr = addr; printf ("## Start Addr = 0x%08lx\n", addr); show_startup_phase(15); /* Loading ok, check if we should attempt an auto-start */ if (((s = getenv("autostart")) != NULL) && (strcmp(s,"yes") == 0)) { char *local_args[2]; local_args[0] = argv[0]; local_args[1] = NULL; printf ("Automatic boot of image at addr 0x%08lX ...\n", load_addr); rcode = do_bootm (cmdtp, 0, 1, local_args); } #ifdef CONFIG_AUTOSCRIPT if (load_addr) { char *s; if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) { printf("Running autoscript at addr 0x%08lX ...\n", load_addr); rcode = autoscript (bd, load_addr); } } #endif return rcode; }
static int do_ping(int argc, char *argv[]) { int ret; uint64_t ping_start; unsigned retries = 0; if (argc < 2) return COMMAND_ERROR_USAGE; net_ping_ip = resolv(argv[1]); if (!net_ping_ip) { printf("unknown host %s\n", argv[1]); return 1; } ping_con = net_icmp_new(net_ping_ip, ping_handler, NULL); if (IS_ERR(ping_con)) { ret = PTR_ERR(ping_con); goto out; } ping_start = get_time_ns(); ret = ping_send(); if (ret) goto out_unreg; ping_state = PING_STATE_INIT; ping_sequence_number = 0; while (ping_state == PING_STATE_INIT) { if (ctrlc()) { ret = -EINTR; break; } net_poll(); if (is_timeout(ping_start, SECOND)) { /* No answer, send another packet */ ping_start = get_time_ns(); ret = ping_send(); if (ret) goto out_unreg; retries++; } if (retries > PKT_NUM_RETRIES) { ret = -ETIMEDOUT; goto out_unreg; } } if (!ret) printf("host %s is alive\n", argv[1]); out_unreg: net_unregister(ping_con); out: if (ret) printf("ping failed: %s\n", strerror(-ret)); return ping_state == PING_STATE_SUCCESS ? 0 : 1; }
int keystone_sgmii_config(struct phy_device *phy_dev, int port, int interface) { unsigned int i, status, mask; unsigned int mr_adv_ability, control; switch (interface) { case SGMII_LINK_MAC_MAC_AUTONEG: mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE | SGMII_REG_MR_ADV_LINK | SGMII_REG_MR_ADV_FULL_DUPLEX | SGMII_REG_MR_ADV_GIG_MODE); control = (SGMII_REG_CONTROL_MASTER | SGMII_REG_CONTROL_AUTONEG); break; case SGMII_LINK_MAC_PHY: case SGMII_LINK_MAC_PHY_FORCED: mr_adv_ability = SGMII_REG_MR_ADV_ENABLE; control = SGMII_REG_CONTROL_AUTONEG; break; case SGMII_LINK_MAC_MAC_FORCED: mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE | SGMII_REG_MR_ADV_LINK | SGMII_REG_MR_ADV_FULL_DUPLEX | SGMII_REG_MR_ADV_GIG_MODE); control = SGMII_REG_CONTROL_MASTER; break; case SGMII_LINK_MAC_FIBER: mr_adv_ability = 0x20; control = SGMII_REG_CONTROL_AUTONEG; break; default: mr_adv_ability = SGMII_REG_MR_ADV_ENABLE; control = SGMII_REG_CONTROL_AUTONEG; } __raw_writel(0, SGMII_CTL_REG(port)); /* * Wait for the SerDes pll to lock, * but don't trap if lock is never read */ for (i = 0; i < 1000; i++) { udelay(2000); status = __raw_readl(SGMII_STATUS_REG(port)); if ((status & SGMII_REG_STATUS_LOCK) != 0) break; } __raw_writel(mr_adv_ability, SGMII_MRADV_REG(port)); __raw_writel(control, SGMII_CTL_REG(port)); mask = SGMII_REG_STATUS_LINK; if (control & SGMII_REG_CONTROL_AUTONEG) mask |= SGMII_REG_STATUS_AUTONEG; status = __raw_readl(SGMII_STATUS_REG(port)); if ((status & mask) == mask) return 0; printf("\n%s Waiting for SGMII auto negotiation to complete", phy_dev->dev->name); while ((status & mask) != mask) { /* * Timeout reached ? */ if (i > SGMII_ANEG_TIMEOUT) { puts(" TIMEOUT !\n"); phy_dev->link = 0; return 0; } if (ctrlc()) { puts("user interrupt!\n"); phy_dev->link = 0; return -EINTR; } if ((i++ % 500) == 0) printf("."); udelay(1000); /* 1 ms */ status = __raw_readl(SGMII_STATUS_REG(port)); } puts(" done\n"); return 0; }
static int do_update_sdcard(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { //struct update_sdcard_device *fd = f_devices; //struct update_sdcard_part *fp; //struct list_head *entry, *n; char *p; unsigned long addr; unsigned long time; int i = 0; int res = 0; int len_read = 0; int err = 0; if (argc != 5) { printf("## [%s():%d] ret_error \n", __func__,__LINE__); goto ret_error; } memset(f_sdcard_part, 0x0, sizeof(f_sdcard_part)*UPDATE_SDCARD_DEV_PART_MAX); len_read = update_sd_do_load(cmdtp, flag, argc, argv, FS_TYPE_FAT, 16); if(len_read > 0) { fboot_lcd_start(); // partition map parse addr = simple_strtoul(argv[3], NULL, 16); p = (char*)addr; p[len_read+1] = '\0'; update_sdcard_sort_string((char*)p, len_read); setenv("fastboot", (char *)p); saveenv(); err = update_sdcard_part_lists_make(p, strlen(p)); if (err >= 0) { struct update_sdcard_part *fp = f_sdcard_part; update_sdcard_part_lists_print(); printf("\n"); for(i=0; i<UPDATE_SDCARD_DEV_PART_MAX; i++, fp++) { if(!strcmp(fp->device, "")) break; if (!strcmp(fp->file_name, "dummy")) continue; if (fs_set_blk_dev(argv[1], (argc >= 3) ? argv[2] : NULL, FS_TYPE_FAT)) { printf("## [%s():%d] ret_error \n", __func__,__LINE__); goto ret_error; } printf("=============================================================\n"); fboot_lcd_flash((char*)fp->file_name, "reading "); time = get_timer(0); len_read = fs_read(fp->file_name, addr, 0, 0); time = get_timer(time); printf("%d bytes read in %lu ms", len_read, time); if (time > 0) { puts(" ("); print_size(len_read / time * 1000, "/s"); puts(")"); } puts("\n"); debug(" %s.%d : %s : %s : 0x%llx, 0x%llx : %s\n", fp->device, fp->dev_no, fp->partition_name, UPDATE_SDCARD_FS_MASK&fp->fs_type?"fs":"img", fp->start, fp->length, fp->file_name); if( 0 >= len_read) continue; fboot_lcd_flash((char*)fp->file_name, "flashing "); { block_dev_desc_t *desc; char cmd[128]; int i = 0, l = 0, p = 0; char *device = fp->device; char *partition_name = fp->partition_name; char *file_name = fp->file_name; uint64_t start = fp->start; uint64_t length = fp->length; int dev = fp->dev_no; unsigned int fs_type = fp->fs_type; int part_num = fp->part_num; //lbaint_t blk, cnt; //int blk_size = 512; length=len_read; memset(cmd, 0x0, sizeof(cmd)); if (!strcmp(device, "eeprom")) { p = sprintf(cmd, "update_eeprom "); if (fs_type & UPDATE_SDCARD_FS_BOOT) l = sprintf(&cmd[p], "%s", "uboot"); else if (fs_type & UPDATE_SDCARD_FS_2NDBOOT) l = sprintf(&cmd[p], "%s", "2ndboot"); else l = sprintf(&cmd[p], "%s", "raw"); p += l; l = sprintf(&cmd[p], " 0x%x 0x%llx 0x%llx", (unsigned int)addr, start, length); p += l; cmd[p] = 0; debug("%s\n", cmd); if(0 > run_command(cmd, 0)) printf("Flash : %s - %s\n", file_name, "FAIL"); else printf("Flash : %s - %s\n", file_name, "DONE"); } else if (!strcmp(device, "mmc")) { sprintf(cmd, "mmc dev %d", dev); //printf("** mmc.%d partition %s (%s)**\n", // dev, partition_name, fs_type&UPDATE_SDCARD_FS_EXT4?"FS":"Image"); /* set mmc devicee */ if (0 > get_device("mmc", simple_itoa(dev), &desc)) { if (0 > run_command(cmd, 0)) { printf("## [%s():%d] ret_error \n", __func__,__LINE__); goto ret_error; } if (0 > run_command("mmc rescan", 0)) { printf("## [%s():%d] ret_error \n", __func__,__LINE__); goto ret_error; } } if (0 > run_command(cmd, 0)) /* mmc device */ { printf("## [%s():%d] ret_error \n", __func__,__LINE__); goto ret_error; } if (0 > get_device("mmc", simple_itoa(dev), &desc)) { printf("## [%s():%d] ret_error \n", __func__,__LINE__); goto ret_error; } memset(cmd, 0x0, sizeof(cmd)); if (fs_type == UPDATE_SDCARD_FS_2NDBOOT || fs_type == UPDATE_SDCARD_FS_BOOT) { if (fs_type == UPDATE_SDCARD_FS_2NDBOOT) p = sprintf(cmd, "update_mmc %d 2ndboot", dev); else p = sprintf(cmd, "update_mmc %d boot", dev); l = sprintf(&cmd[p], " 0x%x 0x%llx 0x%llx", (unsigned int)addr, start, length); p += l; cmd[p] = 0; } else if (fs_type & UPDATE_SDCARD_FS_MASK) { if (update_sdcard_mmc_check_part_table(desc, fp) > 0) { struct update_sdcard_part *fp_1 = fp; int j, cnt=0; uint64_t part_start[UPDATE_SDCARD_DEV_PART_MAX]; uint64_t part_length[UPDATE_SDCARD_DEV_PART_MAX]; char args[128]; printf("Warn : [%s] make new partitions ....\n", partition_name); for (j=i; j<UPDATE_SDCARD_DEV_PART_MAX; j++, fp_1++) { if(!strcmp(fp_1->device, "")) break; part_start[cnt] = fp_1->start; part_length[cnt] = fp_1->length; cnt++; } l = sprintf(args, "fdisk %d %d:", dev, cnt); p = l; for (j= 0; j < cnt; j++) { l = sprintf(&args[p], " 0x%llx:0x%llx", part_start[j], part_length[j]); p += l; } args[p] = 0; printf("%s\n", args); if(0 > run_command(args, 0)) printf("fdisk : %s\n", "FAIL"); else printf("fdisk : %s\n", "DONE"); } //blk = fp->start/blk_size ; //cnt = (length/blk_size) + ((length & (blk_size-1)) ? 1 : 0); //p = sprintf(cmd, "mmc write %x %x %x", addr, blk, cnt); p = sprintf(cmd, "update_mmc %d part %x %d %x", dev, (unsigned int)addr, part_num, (unsigned int)length); } printf("%s\n", cmd); if(0 > run_command(cmd, 0)) printf("Flash : %s - %s\n", file_name, "FAIL"); else printf("Flash : %s - %s\n", file_name, "DONE"); } } } printf("=============================================================\n"); } else { printf("## [%s():%d] ret_error \n", __func__,__LINE__); goto ret_error; } } else { printf("## [%s():%d] ret_error \n", __func__,__LINE__); goto ret_error; } fboot_lcd_status("exit"); while (1) { if (ctrlc()) { printf("update_sdcard end\n\n"); break; } } //fboot_lcd_stop(); //do_reset (NULL, 0, 0, NULL); return res; ret_error: fboot_lcd_stop(); return -1; }
static int do_md(int argc, char ** argv) { s32_t base_addr = 0, nbytes = 64; s32_t i, size = 1; u8_t linebuf[16], line_len; if(argc < 2) { usage(); return -1; } for(i=1; i<argc; i++) { if( !strcmp((const char *)argv[i],"-b") ) size = 1; else if( !strcmp((const char *)argv[i],"-w") ) size = 2; else if( !strcmp((const char *)argv[i],"-l") ) size = 4; else if( !strcmp((const char *)argv[i],"-c") && (argc > i+1)) { nbytes = strtoul((const char *)argv[i+1], NULL, 0); i++; } else if(*argv[i] == '-') { usage(); return (-1); } else if(*argv[i] != '-' && strcmp((const char *)argv[i], "-") != 0) { base_addr = strtoul((const char *)argv[i], NULL, 0); } } if(size == 2) { base_addr = base_addr & (~0x00000001); } else if(size == 4) { base_addr = base_addr & (~0x00000003); } nbytes = nbytes * size; while(nbytes > 0) { line_len = (nbytes > 16) ? 16:nbytes; printf("%08lx: ", base_addr); if(size == 1) { for(i=0; i<line_len; i+= size) *((u8_t *)(&linebuf[i])) = *((u8_t *)(base_addr+i)); for(i=0; i<line_len; i+= size) printf(" %02lx", *((u8_t *)(&linebuf[i]))); } else if(size == 2) { for(i=0; i<line_len; i+= size) *((u16_t *)(&linebuf[i])) = *((u16_t *)(base_addr+i)); for(i=0; i<line_len; i+= size) printf(" %04lx", *((u16_t *)(&linebuf[i]))); } else if(size == 4) { for(i=0; i<line_len; i+= size) *((u32_t *)(&linebuf[i])) = *((u32_t *)(base_addr+i)); for(i=0; i<line_len; i+= size) printf(" %08lx", *((u32_t *)(&linebuf[i]))); } printf("%*s", (16-line_len)*2+(16-line_len)/size+4, (s8_t*)""); for(i=0; i<line_len; i++) { if( (linebuf[i] < 0x20) || (linebuf[i] > 0x7e) ) printf("."); else printf("%c", linebuf[i]); } base_addr += line_len; nbytes -= line_len; printf("\r\n"); if(ctrlc()) return -1; } return 0; }