/* str2short - safely convert string to int16_t * * @str: source string to convert from * @shrt_ptr: pointer where to store result * * returns zero on success * returns (-1) if one of args is NULL, (-2) invalid input, (-3) for *flow */ int str2short(const char * str, int16_t * shrt_ptr) { int rc = (-3); int64_t arg_long = 0; if ( (rc = str2long(str, &arg_long)) != 0 ) { *shrt_ptr = 0; return rc; } if (arg_long < INT16_MIN || arg_long > INT16_MAX) return (-3); *shrt_ptr = (int16_t)arg_long; return 0; } /* str2short(...) */
/* str2int - safely convert string to int32_t * * @str: source string to convert from * @int_ptr: pointer where to store result * * returns zero on success * returns (-1) if one of args is NULL, (-2) invalid input, (-3) for *flow */ int str2int(const char * str, int32_t * int_ptr) { int rc = 0; int64_t arg_long = 0; if ( (rc = str2long(str, &arg_long)) != 0 ) { *int_ptr = 0; return rc; } if (arg_long < INT32_MIN || arg_long > INT32_MAX) return (-3); *int_ptr = (int32_t)arg_long; return 0; } /* str2int(...) */
/* str2char - safely convert string to int8 * * @str: source string to convert from * @chr_ptr: pointer where to store result * * returns zero on success * returns (-1) if one of args is NULL, (-2) or (-3) if conversion fails */ int str2char(const char *str, int8_t * chr_ptr) { int rc = (-3); int64_t arg_long = 0; if (!str || !chr_ptr) { return (-1); } if ((rc = str2long(str, &arg_long)) != 0) { *chr_ptr = 0; return rc; } if (arg_long < INT8_MIN || arg_long > INT8_MAX) { return (-3); } return 0; } /* str2char(...) */
nodeType *long_param(LONG n) { nodeType *p; const char *param; int shift; LONG value; size_t nodeSize; DBG("come in function\n"); if (n < 0 || n >=(batch_argcnt - 1)) { yyerror("invalid str param number"); return NULL; } /* * input: * batch test.cr param1 param2 * args[0] is batch, args[1] is test.cr, args[2] is param1 * We need: * $0 is test.cr, $1 param1, $2 is param2 * so shift the input number */ shift = n + 1; param = batch_args[shift]; value = str2long(param); nodeSize = SIZEOF_NODETYPE(p) + sizeof(longNodeType); p = malloc(nodeSize); if (p == NULL) { yyerror("con_long, malloc node failed!\n"); return NULL; } p->type = typeLongCon; p->longCon.var = value; DBG_NODE(p); return p; }
static int arg_off_size(int argc, char * const argv[], nand_info_t *nand, ulong *off, size_t *size) { int idx = nand_curr_device; #if defined(CONFIG_CMD_MTDPARTS) struct mtd_device *dev; struct part_info *part; u8 pnum; if (argc >= 1 && !(str2long(argv[0], off))) { if ((mtdparts_init() == 0) && (find_dev_and_part(argv[0], &dev, &pnum, &part) == 0)) { if (dev->id->type != MTD_DEV_TYPE_NAND) { puts("not a NAND device\n"); return -1; } *off = part->offset; if (argc >= 2) { if (!(str2long(argv[1], (ulong *)size))) { printf("'%s' is not a number\n", argv[1]); return -1; } if (*size > part->size) *size = part->size; } else { *size = part->size; } idx = dev->id->num; *nand = nand_info[idx]; goto out; } } #endif if (argc >= 1) { if (!(str2long(argv[0], off))) { printf("'%s' is not a number\n", argv[0]); return -1; } } else { *off = 0; } if (argc >= 2) { if (!(str2long(argv[1], (ulong *)size))) { printf("'%s' is not a number\n", argv[1]); return -1; } } else { *size = nand->size - *off; } #if defined(CONFIG_CMD_MTDPARTS) out: #endif printf("device %d ", idx); if (*size == nand->size) puts("whole chip\n"); else printf("offset 0x%lx, size 0x%zx\n", *off, *size); return 0; }
itpType *interpret(nodeType *p) { int nodeSize; int len, n; itpType *pret, *pret1, *pret2, *pret3, *pret4; DBG("come in function\n"); if (p == NULL) return NULL; DBG_NODE(p); pret = malloc(sizeof(itpType)); if (pret == NULL) { yyerror("interpret, malloc pret failed\n"); return NULL; } pret->type = typeLong; pret->ival = 1; /* default to return true */ switch(p->type) { case typeLongCon: pret->ival = p->longCon.var; pret->type = typeLong; DBG_INTERPRET(pret); return pret; break; case typeStrCon: len = strlen(p->strCon.ptr); pret->pstr = malloc(len + 1); if (pret->pstr == NULL) { yyerror("interpret, typeStrCon malloc failed\n"); free_itpType(pret); return NULL; } strncpy(pret->pstr, p->strCon.ptr, len); pret->pstr[len] = '\0'; pret->type = typeStr; DBG_INTERPRET(pret); return pret; break; case typeVar: nodeSize = sizeof(symType); memcpy(pret, &symtab[p->var.index], nodeSize); if (pret->type == typeStr) { len = strlen(pret->pstr); pret->pstr = malloc(len + 1); if (pret->pstr == NULL) { yyerror("interpret, typeVar malloc failed\n"); free_itpType(pret); return NULL; } strncpy(pret->pstr, symtab[p->var.index].pstr, len); pret->pstr[len] = '\0'; } DBG_INTERPRET(pret); return pret; break; case typeOpr: switch(p->opr.name) { case WHILE: pret1 = interpret(p->opr.op[0]); if (pret1 == NULL) { free_itpType(pret); return NULL; } while ((pret1->type == typeLong && pret1->ival) || (pret1->type == typeStr && pret1->pstr)) { pret2 = interpret(p->opr.op[1]); free_itpType(pret1); free_itpType(pret2); pret1 = interpret(p->opr.op[0]); if (pret1 == NULL) { free_itpType(pret); return NULL; } } free_itpType(pret1); DBG_INTERPRET(pret); return pret; break; case IF: pret1 = interpret(p->opr.op[0]); if (pret1 == NULL) return NULL; if ((pret1->type == typeLong && pret1->ival) || (pret1->type == typeStr && pret1->pstr)) { pret2 = interpret(p->opr.op[1]); free_itpType(pret1); free_itpType(pret2); } else if (p->opr.number > 2) { pret2 = interpret(p->opr.op[2]); free_itpType(pret1); free_itpType(pret2); } DBG_INTERPRET(pret); return pret; case PRINT: pret1 = interpret(p->opr.op[0]); if (pret1 == NULL) return NULL; if (pret1->type == typeLong) PRINTLONG(pret1); else if (pret1->type == typeStr) PRINTSTR(pret1); free_itpType(pret1); DBG_INTERPRET(pret); return pret; break; case ';': pret1 = interpret(p->opr.op[0]); pret2 = interpret(p->opr.op[1]); if (pret1) free_itpType(pret1); if (pret2) free_itpType(pret2); DBG_INTERPRET(pret); return pret; break; case '=': pret2 = interpret(p->opr.op[1]); if (pret2 == NULL) return NULL; if (pret2->type == typeLong) symtab[p->opr.op[0]->var.index].ival = pret2->ival; else if (pret2->type == typeStr) { if (symtab[p->opr.op[0]->var.index].type == typeStr) free(symtab[p->opr.op[0]->var.index].pstr); symtab[p->opr.op[0]->var.index].pstr = pret2->pstr; } symtab[p->opr.op[0]->var.index].type = pret2->type; free(pret2); /* do not free pret2->pstr, as it is used by the variable */ DBG_INTERPRET(pret); return pret; break; case UMINUS: pret1 = interpret(p->opr.op[0]); if (pret1 == NULL) return NULL; if (pret1->type == typeLong) { pret->type = typeLong; pret->ival = -pret1->ival; } else { free_itpType(pret1); free_itpType(pret); return NULL; } free_itpType(pret1); DBG_INTERPRET(pret); return pret; break; case PP: if (symtab[p->opr.op[0]->var.index].type == typeLong) { symtab[p->opr.op[0]->var.index].ival += 1; pret->type = typeLong; pret->ival = symtab[p->opr.op[0]->var.index].ival; } else { free_itpType(pret); return NULL; } DBG_INTERPRET(pret); return pret; break; case SS: if (symtab[p->opr.op[0]->var.index].type == typeLong) { symtab[p->opr.op[0]->var.index].ival -= 1; pret->type = typeLong; pret->ival = symtab[p->opr.op[0]->var.index].ival; } else { free_itpType(pret); return NULL; } DBG_INTERPRET(pret); return pret; break; case '+': pret1 = interpret(p->opr.op[0]); pret2 = interpret(p->opr.op[1]); if (pret1 == NULL || pret2 == NULL) { if (pret1 == NULL) free_itpType(pret2); if (pret2 == NULL) free_itpType(pret1); free_itpType(pret); return NULL; } if (pret1->type == typeLong && pret2->type == typeLong) { pret->type = typeLong; pret->ival = pret1->ival + pret2->ival; free_itpType(pret1); free_itpType(pret2); DBG_INTERPRET(pret); return pret; } else if (pret1->type == typeStr && pret2->type == typeStr) { int m = strlen(pret1->pstr); int n = strlen(pret2->pstr); char *s = malloc(m+n+1); if (s == NULL) { free_itpType(pret1); free_itpType(pret2); free_itpType(pret); return NULL; } strncpy(s, pret1->pstr, m); s[m] = '\0'; strncat(s, pret2->pstr, n); s[m+n] = '\0'; free_itpType(pret1); free_itpType(pret2); pret->type = typeStr; pret->pstr = s; DBG_INTERPRET(pret); return pret; } else { yyerror("add type not match\n"); free_itpType(pret1); free_itpType(pret2); free_itpType(pret); return NULL; } break; case '-': case '*': case '/': case '<': case '>': case '%': case AND: case OR: case GE: case LE: pret1 = interpret(p->opr.op[0]); pret2 = interpret(p->opr.op[1]); if (pret1 == NULL || pret2 == NULL) { if (pret1 == NULL) free_itpType(pret2); if (pret2 == NULL) free_itpType(pret1); free_itpType(pret); return NULL; } if (pret1->type == typeLong && pret2->type == typeLong) { pret->type = typeLong; if (p->opr.name == '-') pret->ival = pret1->ival - pret2->ival; else if (p->opr.name == '*') pret->ival = pret1->ival * pret2->ival; else if (p->opr.name == '/') pret->ival = pret1->ival / pret2->ival; else if (p->opr.name == '<') pret->ival = pret1->ival < pret2->ival; else if (p->opr.name == '>') pret->ival = pret1->ival > pret2->ival; else if (p->opr.name == '%') pret->ival = pret1->ival % pret2->ival; else if (p->opr.name == AND) pret->ival = pret1->ival && pret2->ival; else if (p->opr.name == OR) pret->ival = pret1->ival || pret2->ival; else if (p->opr.name == GE) pret->ival = pret1->ival >= pret2->ival; else if (p->opr.name == LE) pret->ival = pret1->ival <= pret2->ival; free_itpType(pret1); free_itpType(pret2); DBG_INTERPRET(pret); return pret; } else { yyerror("type not match\n"); free_itpType(pret1); free_itpType(pret2); free_itpType(pret); return NULL; } break; case EQ: case NE: pret1 = interpret(p->opr.op[0]); pret2 = interpret(p->opr.op[1]); if (pret1 == NULL || pret2 == NULL) { if (pret1 == NULL) free_itpType(pret2); if (pret2 == NULL) free_itpType(pret1); free_itpType(pret); return NULL; } if (pret1->type == typeLong && pret2->type == typeLong) { pret->type = typeLong; if (p->opr.name == EQ) pret->ival = pret1->ival == pret2->ival; else if (pret->type == NE) pret->ival = pret1->ival != pret2->ival; free_itpType(pret1); free_itpType(pret2); DBG_INTERPRET(pret); return pret; } else if (pret1->type == typeStr && pret2->type == typeStr) { pret->type == typeLong; if (p->opr.name == EQ) pret->ival = !strcmp(pret1->pstr, pret2->pstr); else if (p->opr.name == NE) { pret->ival = !!strcmp(pret1->pstr, pret2->pstr); } free_itpType(pret1); free_itpType(pret2); DBG_INTERPRET(pret); return pret; } else { yyerror("add type not match\n"); free_itpType(pret1); free_itpType(pret2); free_itpType(pret); return NULL; } break; case CALL: pret1 = interpret(p->opr.op[0]); if (pret1 == NULL) { free_itpType(pret); return NULL; } if (pret1->type != typeStr) { free_itpType(pret1); free_itpType(pret); return NULL; } pret->type = typeStr; pret->pstr = call_func(pret1->pstr); free_itpType(pret1); if (pret->pstr == NULL) { free_itpType(pret); return NULL; } DBG_INTERPRET(pret); return pret; break; case GET: pret1 = interpret(p->opr.op[0]); pret2 = interpret(p->opr.op[1]); pret3 = interpret(p->opr.op[2]); pret4 = interpret(p->opr.op[3]); if (pret1->type == typeStr && pret2->type == typeLong && pret3->type == typeLong && pret4->type == typeLong) { pret->type = typeStr; pret->pstr = get_func(pret1->pstr, pret2->ival, pret3->ival, pret4->ival); if (pret->pstr == NULL) { free_itpType(pret); pret = NULL; } } free_itpType(pret1); free_itpType(pret2); free_itpType(pret3); free_itpType(pret4); DBG_INTERPRET(pret); return pret; break; case LINES: pret1 = interpret(p->opr.op[0]); pret->type = typeLong; if (pret1->type == typeStr) pret->ival = lines_func(pret1->pstr); else pret->ival = 0; free_itpType(pret1); DBG_INTERPRET(pret); return pret; break; case LEN: pret1 = interpret(p->opr.op[0]); pret->type = typeLong; if (pret1->type == typeStr) pret->ival = strlen(pret1->pstr); else pret->ival = 0; free_itpType(pret1); DBG_INTERPRET(pret); return pret; break; case STR2LONG: pret1 = interpret(p->opr.op[0]); pret->type = typeLong; if (pret1->type != typeStr) { yyerror("str2long need a string as param\n"); free_itpType(pret1); free_itpType(pret); return NULL; } pret->ival = str2long(pret1->pstr); free_itpType(pret1); return pret; break; case LONG2DECSTR: case LONG2HEXSTR: pret1 = interpret(p->opr.op[0]); if (pret1->type != typeLong) { yyerror("long2decstr need a number as param\n"); free_itpType(pret1); free_itpType(pret); return NULL; } else { char *s; int len; s = malloc(MAX_CONVERT_STRLEN); if (s == NULL) { yyerror("malloc for long2decstr failed\n"); free_itpType(pret1); free_itpType(pret); return NULL; } if (p->opr.name == LONG2DECSTR) len = snprintf(s, MAX_CONVERT_STRLEN, "%lld", pret1->ival); else len = snprintf(s, MAX_CONVERT_STRLEN, "0x%llx", pret1->ival); s[len] = '\0'; pret->type = typeStr; pret->pstr = s; return pret; } break; default: yyerror("bad operator!\n"); } default: yyerror("bad node type!\n"); } pret->ival = 0; return pret; }
void get_ini_parm(void) { u32t size = 0; void* ini = 0; u32t btype = hlp_boottype(); if (btype==QSBT_FAT || btype==QSBT_SINGLE) ini = hlp_freadfull("QSINIT.INI",&size,0); if (!ini) ini = hlp_freadfull("OS2LDR.INI",&size,0); if (ini) { char* cfgp = (char*)hlp_memrealloc(ini, size+1); char skipeol = 0, lstart = 1, backch = 0, error = 0, // error in string reason = 0, // collecting now: 1 - section name, 2 - key name, 3 - key section = 0; // 1 - config int value = 0, errline = 1, strln =-1; if (!cfgp) return; else ini=cfgp; cfgp[size++]=0; sto_save(STOKEY_INIDATA,cfgp,size,0); while (size--) { char cc=*cfgp++; if (!size) cc='\n'; if (skipeol && cc=='\n') skipeol=0; if (!skipeol) switch (cc) { case ' ' : case '\t': if (strln>0) strln++; break; case '\n': if (strln>0 && reason<3) { backch=1; error=1; break; } errline++; case '\r': { if (strln > 0 || value) { long rc = str2long(cfgp-1-strln); switch (value) { // "DBPORT" case 1: if (rc>0 && !safeMode) hlp_seroutset(rc,0); break; // "BAUDRATE" case 2: hlp_seroutset(0,rc); break; // "RESETMODE" case 3: if (rc) { if (rc!=43 && rc!=50) rc=25; vio_setmode(rc); } break; // "NOAF" case 4: useAFio=0; break; // "MFSPRINT" case 5: if (rc>0) mfs_rmcmode=0; break; } strln=0; value=0; } lstart=1; reason=0; break; } case '=' : if (reason==2 && strln>0) { value=0; if (section==1) { // "config" int ii=0; while (strList[ii]) if (!cmpname(strList[ii++], cfgp-1, strln)) { value=ii; break; } } if (!value) skipeol=1; else reason=3; strln=0; } else error=1; break; case ';' : if (lstart) skipeol=1; else if ( strln> 0 ) strln++; break; case '[' : if (lstart) { strln=0; reason=1; section=0; } else error=1; break; case ']' : if (reason==1 && !lstart) { if (!cmpname("CONFIG", cfgp-1, strln)) section=1; else section=0; strln=0; skipeol=1; } else error=1; reason=0; break; default: if (lstart==1 && section) { reason=2; strln=0; } lstart=0; if (strln>=0) strln++; } if (backch) { *--cfgp=cc; size++; backch=0; } if (error) { skipeol=1; error=0; reason=0; strln=0; } } //hlp_memfree(ini); } else { #ifdef INITDEBUG serial_init(ComPortAddr = 0x2F8); #endif } log_printf("hi!\n"); log_printf("%s\n",aboutstr); }
static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count, int read) { int ret = 0; while (count--) { /* Raw access */ mtd_oob_ops_t ops = { .datbuf = (u8 *)addr, .oobbuf = ((u8 *)addr) + nand->writesize, .len = nand->writesize, .ooblen = nand->oobsize, .mode = MTD_OOB_RAW }; if (read) ret = nand->read_oob(nand, off, &ops); else ret = nand->write_oob(nand, off, &ops); if (ret) { printf("%s: error at offset %llx, ret %d\n", __func__, (long long)off, ret); break; } addr += nand->writesize + nand->oobsize; off += nand->writesize; } return ret; } int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int i, ret = 0; ulong addr; loff_t off, size, maxsize; char *cmd, *s; nand_info_t *nand; #ifdef CONFIG_SYS_NAND_QUIET int quiet = CONFIG_SYS_NAND_QUIET; #else int quiet = 0; #endif const char *quiet_str = getenv("quiet"); int dev = nand_curr_device; int repeat = flag & CMD_FLAG_REPEAT; /* at least two arguments please */ if (argc < 2) goto usage; if (quiet_str) quiet = simple_strtoul(quiet_str, NULL, 0) != 0; cmd = argv[1]; /* Only "dump" is repeatable. */ if (repeat && strcmp(cmd, "dump")) return 0; if (strcmp(cmd, "info") == 0) { putc('\n'); for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) { if (nand_info[i].name) nand_print_and_set_info(i); } return 0; } if (strcmp(cmd, "device") == 0) { if (argc < 3) { putc('\n'); if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE) puts("no devices available\n"); else nand_print_and_set_info(dev); return 0; } dev = (int)simple_strtoul(argv[2], NULL, 10); set_dev(dev); return 0; } #ifdef CONFIG_ENV_OFFSET_OOB /* this command operates only on the first nand device */ if (strcmp(cmd, "env.oob") == 0) return do_nand_env_oob(cmdtp, argc - 1, argv + 1); #endif /* The following commands operate on the current device, unless * overridden by a partition specifier. Note that if somehow the * current device is invalid, it will have to be changed to a valid * one before these commands can run, even if a partition specifier * for another device is to be used. */ if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE || !nand_info[dev].name) { puts("\nno devices available\n"); return 1; } nand = &nand_info[dev]; if (strcmp(cmd, "bad") == 0) { printf("\nDevice %d bad blocks:\n", dev); for (off = 0; off < nand->size; off += nand->erasesize) if (nand_block_isbad(nand, off)) printf(" %08llx\n", (unsigned long long)off); return 0; } /* * Syntax is: * 0 1 2 3 4 * nand erase [clean] [off size] */ if (strncmp(cmd, "erase", 5) == 0 || strncmp(cmd, "scrub", 5) == 0) { nand_erase_options_t opts; /* "clean" at index 2 means request to write cleanmarker */ int clean = argc > 2 && !strcmp("clean", argv[2]); int scrub_yes = argc > 2 && !strcmp("-y", argv[2]); int o = (clean || scrub_yes) ? 3 : 2; int scrub = !strncmp(cmd, "scrub", 5); int spread = 0; int args = 2; const char *scrub_warn = "Warning: " "scrub option will erase all factory set bad blocks!\n" " " "There is no reliable way to recover them.\n" " " "Use this command only for testing purposes if you\n" " " "are sure of what you are doing!\n" "\nReally scrub this NAND flash? <y/N>\n"; if (cmd[5] != 0) { if (!strcmp(&cmd[5], ".spread")) { spread = 1; } else if (!strcmp(&cmd[5], ".part")) { args = 1; } else if (!strcmp(&cmd[5], ".chip")) { args = 0; } else { goto usage; } } /* * Don't allow missing arguments to cause full chip/partition * erases -- easy to do accidentally, e.g. with a misspelled * variable name. */ if (argc != o + args) goto usage; printf("\nNAND %s: ", cmd); /* skip first two or three arguments, look for offset and size */ if (arg_off_size(argc - o, argv + o, &dev, &off, &size, &maxsize) != 0) return 1; nand = &nand_info[dev]; memset(&opts, 0, sizeof(opts)); opts.offset = off; opts.length = size; opts.jffs2 = clean; opts.quiet = quiet; opts.spread = spread; if (scrub) { if (!scrub_yes) puts(scrub_warn); if (scrub_yes) opts.scrub = 1; else if (getc() == 'y') { puts("y"); if (getc() == '\r') opts.scrub = 1; else { puts("scrub aborted\n"); return -1; } } else { puts("scrub aborted\n"); return -1; } } ret = nand_erase_opts(nand, &opts); printf("%s\n", ret ? "ERROR" : "OK"); return ret == 0 ? 0 : 1; } if (strncmp(cmd, "dump", 4) == 0) { if (argc < 3) goto usage; off = (int)simple_strtoul(argv[2], NULL, 16); ret = nand_dump(nand, off, !strcmp(&cmd[4], ".oob"), repeat); return ret == 0 ? 1 : 0; } if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { size_t rwsize; ulong pagecount = 1; int read; int raw; if (argc < 4) goto usage; addr = (ulong)simple_strtoul(argv[2], NULL, 16); read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ printf("\nNAND %s: ", read ? "read" : "write"); nand = &nand_info[dev]; s = strchr(cmd, '.'); if (s && !strcmp(s, ".raw")) { raw = 1; if (arg_off(argv[3], &dev, &off, &size, &maxsize)) return 1; if (argc > 4 && !str2long(argv[4], &pagecount)) { printf("'%s' is not a number\n", argv[4]); return 1; } if (pagecount * nand->writesize > size) { puts("Size exceeds partition or device limit\n"); return -1; } rwsize = pagecount * (nand->writesize + nand->oobsize); } else { if (arg_off_size(argc - 3, argv + 3, &dev, &off, &size, &maxsize) != 0) return 1; rwsize = size; } if (!s || !strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i")) { if (read) ret = nand_read_skip_bad(nand, off, &rwsize, NULL, maxsize, (u_char *)addr); else ret = nand_write_skip_bad(nand, off, &rwsize, NULL, maxsize, (u_char *)addr, 0); #ifdef CONFIG_CMD_NAND_TRIMFFS } else if (!strcmp(s, ".trimffs")) { if (read) { printf("Unknown nand command suffix '%s'\n", s); return 1; } ret = nand_write_skip_bad(nand, off, &rwsize, NULL, maxsize, (u_char *)addr, WITH_DROP_FFS); #endif #ifdef CONFIG_CMD_NAND_YAFFS } else if (!strcmp(s, ".yaffs")) { if (read) { printf("Unknown nand command suffix '%s'.\n", s); return 1; } ret = nand_write_skip_bad(nand, off, &rwsize, NULL, maxsize, (u_char *)addr, WITH_YAFFS_OOB); #endif } else if (!strcmp(s, ".oob")) { /* out-of-band data */ mtd_oob_ops_t ops = { .oobbuf = (u8 *)addr, .ooblen = rwsize, .mode = MTD_OOB_RAW }; if (read) ret = nand->read_oob(nand, off, &ops); else ret = nand->write_oob(nand, off, &ops); } else if (raw) {
int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { char *boot_device = NULL; int idx; ulong addr, offset = 0; #if defined(CONFIG_CMD_MTDPARTS) struct mtd_device *dev; struct part_info *part; u8 pnum; if (argc >= 2) { char *p = (argc == 2) ? argv[1] : argv[2]; if (!(str2long(p, &addr)) && (mtdparts_init() == 0) && (find_dev_and_part(p, &dev, &pnum, &part) == 0)) { if (dev->id->type != MTD_DEV_TYPE_NAND) { puts("Not a NAND device\n"); return 1; } if (argc > 3) goto usage; if (argc == 3) addr = simple_strtoul(argv[1], NULL, 16); else addr = CONFIG_SYS_LOAD_ADDR; return nand_load_image(cmdtp, &nand_info[dev->id->num], part->offset, addr, argv[0]); } } #endif show_boot_progress(52); switch (argc) { case 1: addr = CONFIG_SYS_LOAD_ADDR; boot_device = getenv("bootdevice"); break; case 2: addr = simple_strtoul(argv[1], NULL, 16); boot_device = getenv("bootdevice"); break; case 3: addr = simple_strtoul(argv[1], NULL, 16); boot_device = argv[2]; break; case 4: addr = simple_strtoul(argv[1], NULL, 16); boot_device = argv[2]; offset = simple_strtoul(argv[3], NULL, 16); break; default: #if defined(CONFIG_CMD_MTDPARTS) usage: #endif cmd_usage(cmdtp); show_boot_progress(-53); return 1; } show_boot_progress(53); if (!boot_device) { puts("\n** No boot device **\n"); show_boot_progress(-54); return 1; } show_boot_progress(54); idx = simple_strtoul(boot_device, NULL, 16); if (idx < 0 || idx >= CONFIG_SYS_MAX_NAND_DEVICE || !nand_info[idx].name) { printf("\n** Device %d not available\n", idx); show_boot_progress(-55); return 1; } show_boot_progress(55); return nand_load_image(cmdtp, &nand_info[idx], offset, addr, argv[0]); }
bool proc_instI(char* mnemonic, char** op, int opcnt, tState *state) { const tInstI *ii = NULL; for (unsigned int i=0; i< ARRSIZE(InstI); i++) { if ( strcasecmp(InstI[i].mnemonic, mnemonic) == 0 ) { ii = &InstI[i]; break; } } if ( !ii ) { return false; } char rs, rt; imm_t con; //16bit if ( ii->type == tInstI::T_Arith || ii->type == tInstI::T_Branch ) { // 0...最後のオペランドが定数になってるふつう形式 // 1...PC相対(ラベルかも?) if ( opcnt != (ii->opercnt+1) ) { throw std::string("Operand count not match"); } // オペランドのレジスタを読み取る short opn[2+1] = {0,0,0}; for(int o=0; o< ii->opercnt; o++) { opn[o] = numreg(trim(op[o])); } rs = opn[ ii->oporder[0] ]; rt = opn[ ii->oporder[1] ]; char *opcon = trim(op[ii->opercnt]); if ( ii->type == tInstI::T_Arith ) { // 定数を読み取る con = (imm_t)str2long(opcon); } else { if ( is_labelhead(opcon[0]) ) { con = 0; // ラベル位置を登録 tLabelPoint tlp; tlp.pnum = state->getPnum(); tlp.label = std::string(opcon); tlp.type = tLabelPoint::T_Branch; tlp.linenum = state->linenum; state->lplaces.push_back(tlp); } else { long lc = str2long(opcon); if ( lc%4 != 0 ) { throw std::string("branch address must be multiples of 4"); } con = (imm_t)(lc/4); } } } else if ( ii->type == tInstI::T_Mem || ii->type == tInstI::T_MemCo ) { // メモリアドレスのオフセットを指定してるやつ if ( opcnt != ii->opercnt ) { throw std::string("Operand count not match"); } if ( ii->type == tInstI::T_Mem ) { //整数 rt = numreg(trim(op[0])); } else { //浮動小数点数 rt = numfreg(trim(op[0])); } // かっこをほぐす char *kakko1 = strchr(op[1], '('); if ( kakko1 == NULL ) { throw std::string("Unknown addressing operand. `(' not found"); } *kakko1 = '\0'; char *kreg = kakko1+1; char *kakko2 = strchr(kreg, ')'); if ( kakko2 == NULL ) { throw std::string("Unknown addressing operand. `)' not found"); } *kakko2 = '\0'; if ( *(kakko2+1) != '\0' ) { throw std::string("Unexpected string `") + std::string(kakko2+1) + std::string("'"); } con = (imm_t)str2long(trim(op[1])); rs = numreg(trim(kreg)); } else if ( ii->type == tInstI::T_SetL ) { // 特殊処理 // ラベルによってその位置のアドレス自体を即値代入する if ( opcnt != (ii->opercnt+1) ) { throw std::string("Operand count not match"); } rs = 0; rt = numreg(trim(op[0])); con = 0; char *opcon = trim(op[ii->opercnt]); if ( !is_labelhead(opcon[0]) ) { throw std::string("Invalid label identifier `") + std::string(opcon) + std::string("'"); } // ラベル位置を登録(上位) tLabelPoint tlpup; tlpup.pnum = state->getPnum(); tlpup.label = std::string(opcon); tlpup.type = tLabelPoint::T_AddrUpp; tlpup.linenum = state->linenum; state->lplaces.push_back(tlpup); // 命令を組み立てて追加(上位)LUIを入れちゃう inst_t inst; inst = (opcode_LUI<<26) | (rs<<21) | (rt<<16) | (con & 0xFFFF); dprintf("0x%x\n", inst); state->dest.push_back(inst); // ラベル位置を登録(下位) tLabelPoint tlp; tlp.pnum = state->getPnum(); tlp.label = std::string(opcon); tlp.type = tLabelPoint::T_AddrLow; tlp.linenum = state->linenum; state->lplaces.push_back(tlp); } else if ( ii->type == tInstI::T_Set ) { // 特殊処理 // 32ビットの即値を2命令で代入する if ( opcnt != (ii->opercnt+1) ) { throw std::string("Operand count not match"); } rs = 0; rt = numreg(trim(op[0])); char *opcon = trim(op[ii->opercnt]); long longimm = str2long(opcon); imm_t upimm = (imm_t)((longimm>>16) & 0xFFFF); if ( upimm != 0 ) { // 命令を組み立てて追加(上位)LUIを入れちゃう inst_t inst; inst = (opcode_LUI<<26) | (rs<<21) | (rt<<16) | (upimm & 0xFFFF); dprintf("0x%x\n", inst); state->dest.push_back(inst); // ORI $rs, $rs, [下位] で下位を入れる rs = rt; } con = (imm_t)(longimm&0xFFFF); } else if ( ii->type == tInstI::T_SetLV || ii->type == tInstI::T_SetCLV ) {
/* * set_arg_value * * sets argument _ai->ai_dest with value specified in _arg * */ static UBYTE set_arg_value(struct arginfo *ai, STRPTR arg, STRPTR arg2, BOOL keywd) { APTR dest = ai->ai_dest; STRPTR param; UBYTE arg_incr = 0; /* set to 1 if arg2 is used */ BOOL arg2used = FALSE; /* evaluate parameter: */ /* if arg is equal to arg-id of ai (no other chars */ /* following), the param is taken from the next arg. */ /* otherwise, the arg is scanned for '=' and the */ /* rest of the arg is taken as param */ if (keywd && !(ai->ai_type == ARG_SWITCH)) { param = arg; while (param[0] && (param[0] != '=')) param++; if (param[0]) param++; else { param = arg2; arg2used = TRUE; if (!param) set_argerr(ASE_REQUIRED_MISS, arg); } } else param = arg; /* * set switch/arg-value */ if (no_argerr) { if (ai->ai_func) { /* call handle function with arg value */ arg_error_hfs = (*(ai->ai_func)) (param); if (arg_error_hfs) set_argerr(ASE_HANDLE_FUNC, param); } else if (ai->ai_type == ARG_SWITCH) /* switch */ *((BOOL *) dest) = TRUE; else { /* * check if argument already set */ if (ai->ai_set && !((ai->ai_flags & ARG_OVERWRITE) || (ai->ai_flags & ARG_MULTIPLE)) ) set_argerr(ASE_OCCURED_TWICE, arg); else ai->ai_set = TRUE; if (no_argerr) { APTR aparam = NULL; DLLIST **dest_list = (DLLIST **) dest; LONG along; /* * get new value and store it in aparam */ if (!param) /* missing param */ set_argerr(ASE_NO_VAL_AFTER_KW, arg); if (ai->ai_type == ARG_TEXT) /* text */ aparam = (APTR) param; else if (ai->ai_type == ARG_LONG) { /* long */ if (!str2long(param, &along)) set_argerr(ASE_INVALID_NUM, arg); else aparam = (APTR) along; /* what a pervert! */ } else if (ai->ai_type == ARG_ENUM) { LONG aenum = strenum(param, ai->ai_misc1.ai_enum, '|', STEN_NOCASE); if (!aenum) set_argerr(ASE_INVALID_ENUM, arg); else aparam = (APTR) aenum; /* what a pervert! */ } #if 0 if (!param) /* missing param */ set_argerr(ASE_NO_VAL_AFTER_KW, arg); if (ai->ai_type == ARG_TEXT) /* text */ *((STRPTR *) dest) = param; else if (ai->ai_type == ARG_LONG) { /* long */ if (!str2long(param, (LONG *) dest)) set_argerr(ASE_INVALID_NUM, arg); } #endif /* * set new value */ if (no_argerr) if (ai->ai_flags & ARG_MULTIPLE) { if (!(*dest_list)) *dest_list = init_dllist(NULL); if (*dest_list) { if (!app_dlnode(*dest_list, aparam)) set_argerr(APE_NO_MEM, arg); } else set_argerr(APE_NO_MEM, arg); } else { if (ai->ai_type == ARG_LONG) *((LONG *) dest) = (LONG) aparam; else if (ai->ai_type == ARG_ENUM) *((LONG *) dest) = (LONG) aparam; else if (ai->ai_type == ARG_TEXT) *((STRPTR *) dest) = (STRPTR) aparam; } } } if (arg2used) /* set return value that arg2 */ arg_incr = 1; /* is skipped outside this func */ } return (arg_incr); }