00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00031 #ifdef HAVE_CONFIG_H
00032 #include "config.h"
00033 #endif
00034 #include <ctype.h>
00035 #include <stdlib.h>
00036 #include <stdio.h>
00037 #include <sys/time.h>
00038 #include "cmdline.h"
00039 #include "jtagpxa250.h"
00040 #include "filemanager.h"
00041 #include "debug.h"
00042 #include <unistd.h>
00043
00045
00047
00048 char *LoadICCmd::getDescr() {
00049 return "loadic <file> <address> [mini]\n"
00050 "Load the file given as parameter into the instruction cache\n"
00051 "If \"mini\" is not specified, code will be loaded in main IC.\n"
00052 "Example:\n\tloadic file.bin 0f0000 mini\n";
00053 }
00054
00055 int LoadICCmd::exec(int argc, char *argv[]) {
00056 assert(pxa250Ptr);
00057 if (argc < 3) {
00058 printf(getDescr());
00059 return 1;
00060 }
00061
00062 unsigned int address;
00063 sscanf(argv[2], "%x", &address);
00064
00065 FILE *f = fileManagerPtr->openFP(argv[1], "r");
00066
00067 if (!f) {
00068 perror(argv[1]);
00069 return 1;
00070 } else {
00071 bool mini = argc >= 4 && strcmp(argv[3], "mini")==0;
00072 unsigned int buffer[8*1024];
00073 int nbi = fread(buffer, 4, 8*1024, f);
00074 printf("%d instructions read from file %s\n", nbi, argv[1]);
00075 printf("Ready to upload in the %s instruction cache, at address 0x%X\n",
00076 mini ? "mini" : "main",
00077 address);
00078 printf("First instruction: 0x%08X (lsB 0x%02X)\n", buffer[0], buffer[0]&0xFF);
00079
00080 #ifdef WORDS_BIGENDIAN
00081 for (int i=0; i<nbi;i++) {
00082 unsigned char *cp= (unsigned char *) &buffer[i];
00083 buffer[i] = JTAGpxa250::charArrayLEToInt(cp);
00084 }
00085 #endif
00086
00087 if (mini & nbi > 512) {
00088 printf("WARNING: trying to load more than 512 instructions in the mini instruction cache!\n");
00089 }
00090
00091 pxa250Ptr->loadIC(mini, address, buffer, nbi);
00092
00093 return 0;
00094 }
00095 }
00096
00097 int CheckCmd::exec(int argc, char *argv[]) {
00098
00099 assert(pxa250Ptr);
00100 if (pxa250Ptr->check()) {
00101 printf("Success\n");
00102 return 0;
00103 } else {
00104 printf("Failure\n");
00105 return 1;
00106 }
00107 }
00108
00109 int InitCmd::exec(int argc, char *argv[]) {
00110
00111 assert(pxa250Ptr);
00112 if (pxa250Ptr->init(argc, argv)) {
00113 printf("Success\n");
00114 return 0;
00115 } else {
00116 printf("Failure\n");
00117 return 1;
00118 }
00119 }
00120
00121 int StopCmd::exec(int argc, char *argv[]) {
00122 assert(pxa250Ptr);
00123 pxa250Ptr->getReadyForUpload();
00124 return 0;
00125 }
00126
00127 int BootCmd::exec(int argc, char *argv[]) {
00128 assert(pxa250Ptr);
00129 pxa250Ptr->boot();
00130 return 0;
00131 }
00132
00133 int ResetCmd::exec(int argc, char *argv[]) {
00134 assert(pxa250Ptr);
00135 pxa250Ptr->jtag->jtagReset();
00136 return 0;
00137 }
00138
00139 int QuitCmd::exec(int argc, char *argv[]) {
00140 printf("quitting.\n");
00141 return -1;
00142 }
00143
00144 int HelpCmd::exec(int argc, char *argv[]) {
00145
00146 if (argc > 1) {
00147
00148 std::vector<Command *>::iterator it;
00149 for (it = cmds.begin(); it != cmds.end(); ++it) {
00150 if (strcmp(argv[1], (*it)->getName()) == 0) {
00151 printf("%s:\n%s\n", argv[1], (*it)->getDescr());
00152 return 0;
00153 }
00154 }
00155 printf("%s: command not found.\n", argv[1]);
00156 return 1;
00157 } else {
00158
00159 std::vector<Command *>::iterator it;
00160 for (it = cmds.begin(); it != cmds.end(); ++it) {
00161 printf("%20s - %s\n", (*it)->getName(), (*it)->getBrief());
00162 }
00163 return 0;
00164 }
00165 }
00166
00167 long long GetTick()
00168 {
00169 struct timeval now;
00170
00171 gettimeofday(&now, NULL);
00172 return (now.tv_sec)*1000+(now.tv_usec)/1000;
00173 }
00174
00175 int LoadCmd::exec(int argc, char *argv[])
00176 {
00177 assert(pxa250Ptr);
00178
00179 unsigned int address;
00180 unsigned int fileSize;
00181 unsigned int fileSizeAligned;
00182 unsigned int *data;
00183 bool halfword = false;
00184
00185 if (argc < 2)
00186 {
00187 printf(getDescr());
00188 return 1;
00189 }
00190 else if (argc == 2)
00191 {
00192 address = 0xa0000000;
00193 }
00194 else
00195 {
00196 sscanf(argv[2], "%x", &address);
00197 if (argc>= 4 && argv[3][0] == 'h')
00198 halfword = true;
00199 }
00200
00201 FILE *fp=fileManagerPtr->openFP(argv[1], "r");
00202 if (fp)
00203 {
00204
00205 fseek(fp, 0, SEEK_END);
00206 fileSize=ftell(fp);
00207 fileSizeAligned = (fileSize&0x3) ? ((fileSize&(~0x3))+4) : fileSize;
00208 fseek(fp, 0, SEEK_SET);
00209
00210 if (halfword) {
00211 fileSizeAligned*=2;
00212 }
00213
00214
00215 data = (unsigned int *)malloc(fileSizeAligned);
00216
00217
00218 if (halfword) {
00219 for (unsigned int i=0; i<fileSizeAligned; i++) {
00220 unsigned short s;
00221 fread(&s, 2, 1, fp);
00222 data[i] = s;
00223 }
00224 } else {
00225 fread(data, 1, fileSize, fp);
00226 }
00227 fclose(fp);
00228
00229
00230 long long startTick=GetTick();
00231 printf("Sending %d words into the device's memory... ", fileSizeAligned / 4);
00232 fflush(stdout);
00233 pxa250Ptr->putData(address, fileSizeAligned / 4, data);
00234 float duration= ((float)GetTick()-startTick)/1000.0f;
00235 printf("done in %.3f s (%.3f KByte/s)\n", duration, fileSizeAligned/(duration*1000.0f));
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 free(data);
00247
00248 return 0;
00249 }
00250 else
00251 return 1;
00252 }
00253
00254 int PutCmd::exec(int argc, char *argv[])
00255 {
00256 assert(pxa250Ptr);
00257
00258 if (argc < 3)
00259 {
00260 printf(getDescr());
00261 return 1;
00262 }
00263
00264 bool halfword = false;
00265 if ((argc >= 4) && (argv[3][0]=='h'))
00266 halfword = true;
00267
00268 unsigned int address, value;
00269 sscanf(argv[1], "%x", &address);
00270 sscanf(argv[2], "%x", &value);
00271 pxa250Ptr->putData(address, 1, &value, halfword);
00272
00273 return 0;
00274 }
00275
00276 int EraseFlashCmd::exec(int argc, char *argv[])
00277 {
00278 assert(pxa250Ptr);
00279 bool fullErase = false;
00280
00281
00282 if (argc == 1)
00283 fullErase = true;
00284
00285
00286 pxa250Ptr->putData(0x555 * 2, 0xaa, true);
00287 pxa250Ptr->putData(0x2aa * 2, 0x55, true);
00288 pxa250Ptr->putData(0x555 * 2, 0x80, true);
00289 pxa250Ptr->putData(0x555 * 2, 0xaa, true);
00290 pxa250Ptr->putData(0x2aa * 2, 0x55, true);
00291
00292
00293 unsigned int address, data;
00294 if (fullErase)
00295 {
00296
00297 address = 0x555 * 2;
00298 pxa250Ptr->putData(0x555 * 2, 0x10, true);
00299 }
00300 else
00301 {
00302
00303 unsigned int i;
00304 for (i=1; i<(unsigned)argc; i++)
00305 {
00306 sscanf(argv[i], "%x", &address);
00307
00308
00309 do
00310 {
00311 pxa250Ptr->getData(address, 1, &data);
00312 } while ((data&(1<<3)) != 0);
00313
00314
00315 pxa250Ptr->putData(address, 0x30, true);
00316 }
00317 }
00318
00319
00320 do
00321 {
00322 pxa250Ptr->getData(address, 1, &data);
00323 } while ((data&(1<<7)) == 0);
00324
00325 return 0;
00326 }
00327
00328 ProgramFlashCmd::ProgramFlashCmd(CmdLine &cmdLine) : cmdLine(cmdLine)
00329 {
00330 }
00331
00338 int ProgramFlashCmd::exec(int argc, char *argv [])
00339 {
00340 assert(pxa250Ptr);
00341
00342 unsigned int address, i;
00343 unsigned int fileSize;
00344 unsigned int fileSizeAligned;
00345 unsigned short *data;
00346
00347 if (argc < 2)
00348 {
00349 printf(getDescr());
00350 return 1;
00351 }
00352 else if (argc == 2)
00353 {
00354 address = 0x00000000;
00355 }
00356 else
00357 {
00358 sscanf(argv[2], "%x", &address);
00359 }
00360
00361
00362 pxa250Ptr->putData(0x555 * 2, 0xaa, true);
00363 pxa250Ptr->putData(0x2aa * 2, 0x55, true);
00364 pxa250Ptr->putData(0x555 * 2, 0x90, true);
00365 unsigned flashid=0;
00366 pxa250Ptr->getData(0, 1, &flashid);
00367
00368 if (flashid != 0x225b0052) {
00369 printf("The flash is not AS29LV800B. Sorry.\n");
00370 return 1;
00371 }
00372
00373
00374 FILE *fp=fileManagerPtr->openFP(argv[1], "r");
00375 if (fp)
00376 {
00377
00378 fseek(fp, 0, SEEK_END);
00379 fileSize=ftell(fp);
00380 fileSizeAligned = (fileSize&0x1) ? fileSize+1 : fileSize;
00381 fclose(fp);
00382
00383
00384 char call[256];
00385
00387 sprintf(call, "flash/enp.lnj %s %x %x\n",
00388 argv[1],
00389 address,
00390 fileSize/2);
00391 printf("calling: \"%s\"\n", call);
00392
00393 long long startTick=GetTick();
00394
00395 if (cmdLine.exec(call))
00396 return 3;
00397
00398 cmdLine.exec("wait");
00399
00400 printf("Embedded flasher returned %d\n", pxa250Ptr->getSavePlace(0));
00401
00402 float duration= ((float)GetTick()-startTick)/1000.0f;
00403 printf("done in %.3f s (%.3f KByte/s)\n", duration, fileSizeAligned/(duration*1000.0f));
00404
00405 return 0;
00406 }
00407 else
00408 return 2;
00409 }
00410
00411 int GetCmd::exec(int argc, char *argv[])
00412 {
00413 assert(pxa250Ptr);
00414 unsigned int address;
00415 unsigned int size;
00416 unsigned int *data;
00417
00418 if (argc < 2)
00419 {
00420 printf(getDescr());
00421 return 1;
00422 }
00423 else if (argc == 2)
00424 {
00425 size = 1;
00426 }
00427 else
00428 {
00429 sscanf(argv[2], "%x", &size);
00430 }
00431
00432 sscanf(argv[1], "%x", &address);
00433
00434 data = (unsigned int *)malloc(size*sizeof(unsigned int));
00435 pxa250Ptr->getData(address, size, data);
00436
00437 for (unsigned i=0; i<size; i++)
00438 {
00439 printf("%08x : %08x\n", address+(i*4), data[i]);
00440 }
00441
00442 free(data);
00443
00444 return 0;
00445 }
00446
00447 int ExecCmd::exec(int argc, char *argv[])
00448 {
00449 assert(pxa250Ptr);
00450 unsigned int address;
00451 unsigned int sp;
00452
00453 if (argc<2)
00454 {
00455 address=0xa0000000;
00456 sp=0xa0000000+(64*1024*1024);
00457 }
00458 else if (argc<3)
00459 {
00460 sscanf(argv[1], "%x", &address);
00461 sp=0xa0000000+(64*1024*1024);
00462 }
00463 else
00464 {
00465 sscanf(argv[1], "%x", &address);
00466 sscanf(argv[2], "%x", &sp);
00467 }
00468
00469 pxa250Ptr->execute(address, sp);
00470
00471 return 0;
00472 }
00473
00474 int ExtBreakCmd::exec(int argc, char *argv[]) {
00475 assert(pxa250Ptr);
00476 pxa250Ptr->extBreak();
00477
00478 return 0;
00479 }
00480
00481 int RebootCmd::exec(int argc, char *argv[]) {
00482 assert(pxa250Ptr);
00483 pxa250Ptr->reboot();
00484 return 0;
00485 }
00486
00487 int ContinueCmd::exec(int argc, char *argv[]) {
00488 assert(pxa250Ptr);
00489 pxa250Ptr->continueCmd();
00490 return 0;
00491 }
00492
00493 int RegisterCmd::exec(int argc, char *argv[]) {
00494 assert(pxa250Ptr);
00495 if (argc < 2) {
00496 printf("%s",getDescr());
00497 return 1;
00498 }
00499
00500 unsigned int reg = strtoul(argv[1], 0, 10);
00501
00502 if (argc >= 3) {
00503
00504 unsigned int val = strtoul(argv[2], 0, 16);
00505
00506 return pxa250Ptr->setSavePlace(reg, val) ? 0 : 2;
00507 } else {
00508
00509 unsigned int val = pxa250Ptr->getSavePlace(reg);
00510 printf("Register %d = %08x (%d)\n", reg, val, val);
00511 return 0;
00512 }
00513 }
00514
00515 int HwBreakCmd::exec(int argc, char *argv[]) {
00516
00517 if (argc < 2) {
00518 printf("%s", getDescr());
00519 return 1;
00520 }
00521
00522
00523 bool enable;
00524
00525 if (strcmp("on", argv[1]) == 0) {
00526 enable = true;
00527 } else {
00528 if (strcmp("off", argv[1]) == 0)
00529 enable = false;
00530 else {
00531 printf("%s", getDescr());
00532 return 2;
00533 }
00534 }
00535
00536
00537 unsigned int addr;
00538
00539 if (argc >= 3)
00540 addr = strtoul(argv[2], 0, 16);
00541 else
00542 addr = pxa250Ptr->getSavePlace(15);
00543
00544 JTAGpxa250::Cp15Reg reg=JTAGpxa250::IBCR0;
00545
00546 if (argc >= 4) {
00547 switch (argv[3][0]) {
00548 case '0': reg = JTAGpxa250::IBCR0; break;
00549 case '1': reg = JTAGpxa250::IBCR1; break;
00550 default:
00551 printf("%s", getDescr());
00552 return 3;
00553 }
00554 }
00555
00556
00557 if (pxa250Ptr->setCp15DebugRegister(addr | ( enable ? 1 : 0), reg))
00558 return 0;
00559 else
00560 return 4;
00561 }
00562
00563 int WaitCmd::exec(int argc, char *argv[]) {
00564
00565 while (!pxa250Ptr->targetReady()) {
00566 usleep(100);
00567 pxa250Ptr->pollForTX();
00568 }
00569 return 0;
00570 }
00571
00573
00575
00577
00578 commands.push_back(new InitCmd());
00579 commands.push_back(new CheckCmd());
00580 commands.push_back(new StopCmd());
00581 commands.push_back(new LoadICCmd());
00582 commands.push_back(new QuitCmd());
00583 commands.push_back(new ResetCmd());
00584 commands.push_back(new BootCmd());
00585 commands.push_back(new LoadCmd());
00586 commands.push_back(new PutCmd());
00587 commands.push_back(new GetCmd());
00588 commands.push_back(new ExecCmd());
00589 commands.push_back(new ExtBreakCmd());
00590 commands.push_back(new ContinueCmd());
00591 commands.push_back(new RebootCmd());
00592 commands.push_back(new RegisterCmd());
00593 commands.push_back(new HwBreakCmd());
00594 commands.push_back(new HelpCmd(commands));
00595
00596 commands.push_back(new WaitCmd());
00597 commands.push_back(new ProgramFlashCmd(*this));
00598 }
00599
00601 CmdLine::~CmdLine() {
00602 std::vector<Command *>::iterator it;
00603 for (it = commands.begin(); it != commands.end(); ++it) {
00604 delete *it;
00605 *it = 0;
00606 }
00607 }
00608
00625 int CmdLine::exec(const char *cmdLine, int argc, char **argv) {
00626
00627 char *cmd = strdup(cmdLine);
00628 char *words[256];
00629 int nbWords = splitString(cmd, words, 256, " \t\r\n");
00630
00631 assert(cmd);
00632 assert(words);
00633
00634
00635 if ((nbWords==0) || (words[0][0] == '#')) {
00636 free(cmd);
00637 return 0;
00638 }
00639
00640
00641 for (int i=0; i< nbWords; i++) {
00642 if (words[i][0] == '#') {
00643 nbWords = i;
00644 break;
00645 }
00646
00647 if (argc && words[i][0] == '\\' && isdigit(words[i][1])) {
00648 long p = strtoul(words[i] + 1, 0, 10);
00649 if (p < 0) p = 0;
00650 if (p < argc)
00651 words[i] = argv[p];
00652 }
00653 }
00654
00655
00656 std::vector<Command *>::iterator it;
00657 for (it = commands.begin(); it != commands.end(); ++it) {
00658 if (strcmp((*it)->getName(), words[0]) == 0) {
00659 int ret= (*it)->exec(nbWords, words);
00660 free(cmd);
00661 return ret;
00662 }
00663 }
00664
00665
00666 FILE *f = fileManagerPtr->openFP(words[0], "rt");
00667 if (f) {
00668 char line[256];
00669 int ln=0;
00670 while (fgets(line, sizeof(line), f)) {
00671 ln++;
00672 debugMessage(CMD_SCRIPT_DEBUG, "%s:%d: %s\n", words[0], ln, line);
00673 int r=exec(line, nbWords, words);
00674 if (r) {
00675 printf("%s:%d: command returned %d\n",
00676 words[0], ln, r);
00677 fclose(f);
00678 free(cmd);
00679 return -3;
00680 }
00681
00682 }
00683 fclose(f);
00684 free(cmd);
00685 return 0;
00686 }
00687
00688 fprintf(stderr, "%s: command not found\n", words[0]);
00689 free(cmd);
00690 return -2;
00691 }
00692
00693 int CmdLine::getNextToken(const char *string, const char *delim) {
00694
00695 for (int i=0; string[i]; i++) {
00696 for (int c=0; delim[c]; c++) {
00697 if (string[i] != delim[c])
00698 return i;
00699 }
00700 }
00701 return -1;
00702 }
00703
00704
00716 int CmdLine::splitString(char *inputString, char **outputArray,
00717 unsigned arraySize, const char *delimiters)
00718 {
00719 char *c;
00720 unsigned arrayPos=0;
00721 int inWord = 0;
00722
00723 if (!inputString) return 0;
00724 for (c= inputString; *c; c++) {
00725 if (index(delimiters, *c)) {
00726 *c = 0;
00727 inWord = 0;
00728 } else {
00729 if (!inWord && arrayPos < arraySize) {
00730 inWord = 1;
00731 outputArray[arrayPos++] = c;
00732 }
00733 }
00734 }
00735 return arrayPos;
00736 }
00737