📄 jtagpxa250.cpp
字号:
// there's 1024 lines of 8 instructions 32 bits width if (nbInst > 8*1024) return false; } unsigned int addr = startAddr; unsigned int i; for (i=0; i+8 < nbInst ; i+=8) { loadICLine(mini, addr, instructions + i); printf("\r%d on %d instructions loaded. ", i+8, nbInst); fflush(stdout); addr += 8*4; } unsigned int remain = nbInst % 8; if (remain) { unsigned int data[8]; // buffer, filled with nop. for (unsigned int j=0; j<8; j++) { if (j < remain) data[j] = instructions[ nbInst - remain + j ]; else data[j] = 0x0000A0E1; // NOP (?) } printf("adding %d nops\n", 8 - remain); loadICLine(mini, addr, data); } printf("\r%d instructions successfully loaded. \n", nbInst); return true; // everything went ok.}// returs true on success, false on errorbool JTAGpxa250::writeRX(unsigned int val){ unsigned char cdata[5]; // 36 bits needs 5 bytes int retryCount=0; // Issue JTAG DBGRX Command ireg(JTAG_DBGRX); do { // set dbg. d and dbg.flush to 0 intToCharArrayLE((val << 3) | 0x0, cdata); cdata[4] = (val >> 29); // set dbg.v to 1 cdata[4] |= 0x8; // write 36 bits jtag->dreg(cdata, 36); if (retryCount) { printf("\rJTAG : writeRX : Retry to put jtag-data [%08x] (retry %d) ", val, retryCount); fflush(stdout); } if (++retryCount > MAX_RETRY_COUNT) { printf("\nJTAG : writeRX : Writing RX failed\n"); return false; } } while ( cdata[0]&0x1 ); return true;}//! write RX fast, do not wait for answervoid JTAGpxa250::fastWriteRX(unsigned int val, bool cont){ unsigned char cdata[5]; // 36 bits needs 5 bytes // set dbg. d to one and dbg.flush to 0 intToCharArrayLE((val << 3) | ((cont) ? 0x4 : 0x0) , cdata); cdata[4] = (val >> 29); // set dbg.v to 1 cdata[4] |= 0x8; // write 36 bits, write only jtag->dreg(cdata, 36, true); // flush queu when high speed transfer is finished if (!cont) jtag->flushQueue();}/*! read the TX JTAG register. * \param val a pointer on a 32 bits area to store the result * \param max_retry the number of retry allowed. If 0 is given, this function will poll * \return true on a read success, false if there's nothing to read from TX */bool JTAGpxa250::readTX(unsigned int *val, int max_retry){ unsigned char cdata[5]; // 36 bits needs 5 bytes int retryCount=0; // Issue JTAG DBGTX Command ireg(JTAG_DBGTX); while (true) { // set dbg.d, dbg.v and dbg.flush to 0 memset(cdata, 0, 5); jtag->dreg(cdata, 36); if (cdata[0]&0x1==1) { *val=(cdata[0]>>3)|(cdata[1]<<5)|(cdata[2]<<13)|(cdata[3]<<21)|((cdata[4]&0x7)<<29); return true; } if (retryCount>=max_retry) break; printf("\rJTAG : readTX : Retry to get jtag-data (retry %d) ", retryCount++); fflush(stdout); } if (max_retry > 0) printf("\nJTAG : readTX : Reading TX failed. Got %02x %02x %02x %02x %02x\n", cdata[4], cdata[3], cdata[2], cdata[1], cdata[0]); return false;}/*! This function loads size 32 bits words data into any address. * * \param startAddr address where the transfer begins * \param words number of 32 bit words of the transfer, size in byte is words*4 * \param data data array * \param halfword if true, only 16 bits per word will be written, and the address * counter will be incremented by 2 instead of 4. */void JTAGpxa250::putData(unsigned int startAddr, unsigned int words, unsigned int data[], bool halfword){ if (!readyForTargetCommand()) return; // Issue JTAG DBGRX Command unsigned char instr = JTAG_DBGRX; ireg(instr); // Send data writeRX((unsigned int)'p'); writeRX(startAddr); writeRX(halfword ? 1 : 0); // 16 or 32 bits access ? 0 means 32. unsigned int pos=0; unsigned int sum=0; while (pos<words) { fastWriteRX(data[pos], true); sum += data[pos]; pos++; } fastWriteRX(0, false); unsigned int result; if (!readTX(&result)) { printf("Error: can't read checksum !\n"); } else { if (result != sum) printf("Checksum error: %08X != %08X !\n", sum, result); } pollForTX();}/*! This function save size 32 bits words data from any address. * * \param startAddr address where the transfer begins * \param words size in 32 bit words of the transfer * \param data data array */void JTAGpxa250::getData(unsigned int startAddr, unsigned int words, unsigned int data[]){ if (!readyForTargetCommand()) return; // Issue JTAG DBGRX Command unsigned char instr = JTAG_DBGRX; ireg(instr); // Get data writeRX((unsigned int)'g'); writeRX(startAddr); writeRX(words); unsigned int pos=0; // Issue JTAG DBGTX Command instr = JTAG_DBGTX; ireg(instr); while (pos<words) { //if (readTX(data+pos)) // printf("word %d is success\n", pos); readTX(data+pos); pos++; } pollForTX();}// This function execute from an address with a given stack pointer//// \param startAddre address where the execution will begin// \param spAddr address of the stack pointer (grows downside)void JTAGpxa250::execute(unsigned int startAddr, unsigned int spAddr){ if (!isTargetReady) return; savePlaces[save_LR] = startAddr; savePlaces[save_R13] = spAddr; continueCmd();}void JTAGpxa250::extBreak() { // the SELCDSR instruction selects access to // the DCSR JTAG Data register, allowing us to // generate an external debug break. unsigned char instr = JTAG_DCSR; ireg(instr); unsigned char data[5]; unsigned int dcsr = DCSR_GE | DCSR_H; // enable, halt intToCharArrayLE((dcsr << 3) | 0x4, data); // external debug event, no hold_rst data[4] = (dcsr >> 29); jtag->dreg(data,36); printf("DCSR: %08X\n", (data[4] << 29) | (data[3] << 21) | (data[2] << 13) | (data[1] << 5) | (data[0] >> 3)); doPolling = true; pollForTX();}void JTAGpxa250::reboot() { jtag->cpuReset(true); jtag->cpuReset(false); isTargetReady= false; pollForTX();} void JTAGpxa250::pollForTX() { unsigned int tx; if (!doPolling) return; while (readTX(&tx, 0)) { if ((tx == 0xFFFFFFFF) || (tx==0)) { printf("Target disconnected.\n"); doPolling = false; return; } switch (tx & TARGET_TO_HOST_CMD_MASK) { case SAVE_ON_HOST: { unsigned int place = tx & (~TARGET_TO_HOST_CMD_MASK); assert(place < NBR_OF_SAVE_PLACES); readTX(savePlaces + place); //printf("Saving in place %d value %08X\n", place, savePlaces[place]); break; } case LOAD_FROM_HOST: { unsigned int place = tx & (~TARGET_TO_HOST_CMD_MASK); assert(place < NBR_OF_SAVE_PLACES); ireg(JTAG_DBGRX); writeRX(savePlaces[place]); break; } case TARGET_READY_FOR_CMD: printf("(target ready at PC=%08X)\n", savePlaces[15]); isTargetReady = true; for (std::vector<Callback>::iterator it=targetReadyCallback.begin(); it!=targetReadyCallback.end(); ++it) it->callback(it->arg); break; default: // we don't understand the debug handler :/ printf("Unknown target to host command: 0x%08X (%d, %c)\n", tx, tx, tx); } } // nothing to do...}void JTAGpxa250::ireg(unsigned char instr) { if (currentIREG != instr) { jtag->ireg(&instr); currentIREG=instr; }}void JTAGpxa250::continueCmd() { if (!readyForTargetCommand()) return; // Issue JTAG DBGRX Command ireg(JTAG_DBGRX); // Send data writeRX((unsigned int)'c'); pollForTX();}bool JTAGpxa250::readyForTargetCommand() { if (isTargetReady) { isTargetReady=false; return true; } printf("warning: trying to issue a command when the debug handler is not ready!\n"); return false;}bool JTAGpxa250::setSavePlace(unsigned int place, unsigned int value) { assert(place < NBR_OF_SAVE_PLACES); savePlaces[place] = value; if (isTargetReady) { return true; } printf("Warning: setting a register while the target is not ready!\n"); return false;}unsigned int JTAGpxa250::getSavePlace(unsigned int place) { assert(place < NBR_OF_SAVE_PLACES); if (!isTargetReady) printf("Warning: trying to read a register while the target is not ready!\n"); return savePlaces[place];}bool JTAGpxa250::setCp15DebugRegister(unsigned int value, Cp15Reg reg) { if (!readyForTargetCommand()) return false; // SetBreakpoint command writeRX('b'); // send the number of the register writeRX((unsigned int) reg); // send the value writeRX(value); pollForTX(); return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -