/*! \file jtagarm7tdmi.c
- \author Matthew Carpenter <matt@inguardians.com>
\brief ARM7TDMI JTAG (AT91R40008)
*/
http://hri.sourceforge.net/tools/jtag_faq_org.html
********************************/
+
+
+
+
+
/****************************************************************
Enabling jtag likely differs with most platforms. We will attempt to enable most from here. Override jtagarm7tdmi_start() to extend for other implementations
ARM7TDMI enables three different scan chains:
jtag_arm_tcktock();
jtag_arm_tcktock();
jtag_arm_tcktock();
+ jtag_arm_tcktock();
+ jtag_arm_tcktock();
+ jtag_arm_tcktock();
jtag_arm_tcktock(); // now in Reset state
CLRTMS;
jtag_arm_tcktock(); // now in Run-Test/Idle state
void jtag_arm_tcktock() {
CLRTCK;
- //PLEDOUT^=PLEDPIN;
+ PLEDOUT^=PLEDPIN;
SETTCK;
- //PLEDOUT^=PLEDPIN;
+ PLEDOUT^=PLEDPIN;
}
+//! Set up the pins for JTAG mode.
+void armjtagsetup(){
+ P5DIR|=MOSI+SCK+TMS;
+ P5DIR&=~MISO;
+ P5OUT|=0xFFFF;
+ P5OUT=0;
+ P4DIR|=TST;
+ P2DIR|=RST;
+ msdelay(10);
+}
+
+
// ! Start JTAG, setup pins, reset TAP and return IDCODE
unsigned long jtagarm7tdmi_start() {
- debugstr("_start");
- jtagsetup();
+ armjtagsetup();
//Known-good starting position.
//Might be unnecessary.
SETTST;
SETRST;
- delay(0xFF);
+ delay(0x2);
- //Entry sequence from Page 67 of SLAU265A for 4-wire JTAG
CLRRST;
- delay(20);
+ delay(2);
CLRTST;
msdelay(10);
/*
P5DIR &=~RST;
*/
- delay(0xFF);
+ delay(0x2);
jtagarm7tdmi_resettap();
return jtagarm7tdmi_idcode();
}
unsigned int bit;
unsigned long high = 1;
unsigned long mask;
- debugstr("_transn");
- for (bit=(bitcount-1)/16; bit>0; bit--)
- high <<= 16;
- high <<= ((bitcount-1)%16);
+ for (bit=(bitcount-1)/8; bit>0; bit--)
+ high <<= 8;
+ high <<= ((bitcount-1)%8);
mask = high-1;
}
}
} else {
- for (bit=bitcount; bit>0; bit++) {
+ for (bit = bitcount; bit > 0; bit--) {
/* write MOSI on trailing edge of previous clock */
if (word & high)
{SETMOSI;}
jtag_arm_tcktock();
/* read MISO on trailing edge */
- word |= READMISO;
+ word |= (READMISO);
}
}
+
+
+ SETMOSI;
if (end){
// exit state
//! SAMPLE verb
//unsigned long jtagarm7tdmi_sample() {
-// debugstr("_sample");
// jtagarm7tdmi_ir_shift4(ARM7TDMI_IR_SAMPLE); // ???? same here.
// return jtagtransn(0,32);
//}
}
//! ARM7TDMI_IR_CLAMP 0x5
-unsigned long jtagarm7tdmi_clamp() {
- jtagarm7tdmi_resettap();
- SHIFT_IR;
- jtagarmtransn(ARM7TDMI_IR_CLAMP, 4, LSB, END, NORETIDLE);
- SHIFT_DR;
- return jtagarmtransn(0, 32, LSB, END, RETIDLE);
-}
+//unsigned long jtagarm7tdmi_clamp() {
+// jtagarm7tdmi_resettap();
+// SHIFT_IR;
+// jtagarmtransn(ARM7TDMI_IR_CLAMP, 4, LSB, END, NORETIDLE);
+// SHIFT_DR;
+// return jtagarmtransn(0, 32, LSB, END, RETIDLE);
+//}
//! ARM7TDMI_IR_HIGHZ 0x7
-unsigned char jtagarm7tdmi_highz() {
- jtagarm7tdmi_resettap();
- SHIFT_IR;
- return jtagarmtransn(ARM7TDMI_IR_HIGHZ, 4, LSB, END, NORETIDLE);
-}
+//unsigned char jtagarm7tdmi_highz() {
+// jtagarm7tdmi_resettap();
+// SHIFT_IR;
+// return jtagarmtransn(ARM7TDMI_IR_HIGHZ, 4, LSB, END, NORETIDLE);
+//}
//! define ARM7TDMI_IR_CLAMPZ 0x9
-unsigned char jtagarm7tdmi_clampz() {
- jtagarm7tdmi_resettap();
- SHIFT_IR;
- return jtagarmtransn(ARM7TDMI_IR_CLAMPZ, 4, LSB, END, NORETIDLE);
-}
+//unsigned char jtagarm7tdmi_clampz() {
+// jtagarm7tdmi_resettap();
+// SHIFT_IR;
+// return jtagarmtransn(ARM7TDMI_IR_CLAMPZ, 4, LSB, END, NORETIDLE);
+//}
//! Connect the appropriate scan chain to TDO/TDI. SCAN_N, INTEST, ENDS IN SHIFT_DR!!!!!
unsigned long jtagarm7tdmi_scan(int chain, int testmode) { // PROVEN
- debugstr("_scan");
/*
When selecting a scan chain the “Run Test/Idle” state should never be reached, other-
wise, when in debug state, the core will not be correctly isolated and intrusive
// put in test mode...
SHIFT_IR;
jtagarmtransn(testmode, 4, LSB, END, RETIDLE);
-
- current_chain = chain;
-
return(retval);
}
//! push an instruction into the pipeline - Assumes scan-chain 1 is already INTEST
unsigned long jtagarm7tdmi_instr_primitive(unsigned long instr, char breakpt){
unsigned long retval;
+ //jtagarm7tdmi_resettap(); // FIXME: DEBUG: seems necessary for some reason. ugh.
jtagarm7tdmi_scan_intest(1);
+
SHIFT_DR;
// if the next instruction is to run using MCLK (master clock), set TDI
if (breakpt)
CLRMOSI;
count_dbgspd_instr_since_debug++;
}
-
jtag_arm_tcktock();
// Now shift in the 32 bits
unsigned long jtagarm7tdmi_nop(char breakpt){
+ //jtagarm7tdmi_scan_intest(1);
+ //SHIFT_DR
+ //return jtagarmtransn(ARM_INSTR_NOP, 32, LSB, END, NORETIDLE);
return jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, breakpt);
}
unsigned long jtagarm7tdmi_setMode_ARM(){ // PROVEN
unsigned long retval = 0xff;
while ((jtagarm7tdmi_get_dbgstate() & JTAG_ARM7TDMI_DBG_TBIT)&& retval-- > 0){
- jtagarm7tdmi_scan_intest(1);
cmddataword[6] = jtagarm7tdmi_instr_primitive(THUMB_INSTR_NOP,0);
cmddataword[1] = jtagarm7tdmi_instr_primitive(THUMB_INSTR_STR_R0_r0,0);
cmddataword[2] = jtagarm7tdmi_instr_primitive(THUMB_INSTR_MOV_R0_PC,0);
cmddataword[4] = jtagarm7tdmi_instr_primitive(THUMB_INSTR_BX_PC,0);
cmddataword[5] = jtagarm7tdmi_instr_primitive(THUMB_INSTR_NOP,0);
cmddataword[6] = jtagarm7tdmi_instr_primitive(THUMB_INSTR_NOP,0);
- delay(10);
+ jtagarm7tdmi_resettap(); // seems necessary for some reason. ugh.
}
return(retval);
}
SHIFT_DR;
retval = jtagarmtransn(data, 32, LSB, NOEND, NORETIDLE); // send in the data - 32-bits lsb
temp = jtagarmtransn(reg, 5, LSB, NOEND, NORETIDLE); // send in the register address - 5 bits lsb
- jtagarmtransn(1, 1, LSB, END, RETIDLE); // send in the register address - 5 bits lsb
+ jtagarmtransn(1, 1, LSB, END, RETIDLE); // send in the WRITE bit
//SETTMS; // Last Bit - Exit UPDATE_DR
//// is this update a read/write or just read?
/************************* ICEBreaker/EmbeddedICE Stuff ******************************/
//! Grab debug register
unsigned long jtagarm7tdmi_get_dbgstate() { // ICE Debug register, *NOT* ARM register DSCR // PROVEN
+ //jtagarm7tdmi_resettap();
return eice_read(EICE_DBGSTATUS);
}
// store watchpoint info? - not right now
// FIXME: store info
- // write 0 in watchpoint 0 address
- eice_write(EICE_WP0ADDR, addr);
- // write 0xffffffff in watchpoint 0 address mask
- eice_write(EICE_WP0ADDRMASK, addrmask);
- // write 0 in watchpoint 0 data
- eice_write(EICE_WP0DATA, data);
- // write 0xffffffff in watchpoint 0 data mask
- eice_write(EICE_WP0DATAMASK, datamask);
- // write 0x00000100 in watchpoint 0 control value register (enables watchpoint)
- eice_write(EICE_WP0CTRL, ctrlmask);
- // write 0xfffffff7 in watchpoint 0 control mask - only detect the fetch instruction
- eice_write(EICE_WP0CTRLMASK, ctrlmask);
+ eice_write(EICE_WP0ADDR, addr); // write 0 in watchpoint 0 address
+ eice_write(EICE_WP0ADDRMASK, addrmask); // write 0xffffffff in watchpoint 0 address mask
+ eice_write(EICE_WP0DATA, data); // write 0 in watchpoint 0 data
+ eice_write(EICE_WP0DATAMASK, datamask); // write 0xffffffff in watchpoint 0 data mask
+ eice_write(EICE_WP0CTRL, ctrlmask); // write 0x00000100 in watchpoint 0 control value register (enables watchpoint)
+ eice_write(EICE_WP0CTRLMASK, ctrlmask); // write 0xfffffff7 in watchpoint 0 control mask - only detect the fetch instruction
}
//! Set and Enable Watchpoint 1
// store watchpoint info? - not right now
// FIXME: store info
- // write 0 in watchpoint 1 address
- eice_write(EICE_WP1ADDR, addr);
- // write 0xffffffff in watchpoint 1 address mask
- eice_write(EICE_WP1ADDRMASK, addrmask);
- // write 0 in watchpoint 1 data
- eice_write(EICE_WP1DATA, data);
- // write 0xffffffff in watchpoint 1 data mask
- eice_write(EICE_WP1DATAMASK, datamask);
- // write 0x00000100 in watchpoint 1 control value register (enables watchpoint)
- eice_write(EICE_WP1CTRL, ctrl);
- // write 0xfffffff7 in watchpoint 1 control mask - only detect the fetch instruction
- eice_write(EICE_WP1CTRLMASK, ctrlmask);
+ eice_write(EICE_WP1ADDR, addr); // write 0 in watchpoint 1 address
+ eice_write(EICE_WP1ADDRMASK, addrmask); // write 0xffffffff in watchpoint 1 address mask
+ eice_write(EICE_WP1DATA, data); // write 0 in watchpoint 1 data
+ eice_write(EICE_WP1DATAMASK, datamask); // write 0xffffffff in watchpoint 1 data mask
+ eice_write(EICE_WP1CTRL, ctrl); // write 0x00000100 in watchpoint 1 control value register (enables watchpoint)
+ eice_write(EICE_WP1CTRLMASK, ctrlmask); // write 0xfffffff7 in watchpoint 1 control mask - only detect the fetch instruction
}
//! Disable Watchpoint 0
void jtagarm7tdmi_disable_watchpoint0(){
- // write 0 in watchpoint 0 control value - disables watchpoint 0
- eice_write(EICE_WP0CTRL, 0x0);
+ eice_write(EICE_WP0CTRL, 0x0); // write 0 in watchpoint 0 control value - disables watchpoint 0
}
//! Disable Watchpoint 1
void jtagarm7tdmi_disable_watchpoint1(){
- // write 0 in watchpoint 0 control value - disables watchpoint 0
- eice_write(EICE_WP1CTRL, 0x0);
+ eice_write(EICE_WP1CTRL, 0x0); // write 0 in watchpoint 0 control value - disables watchpoint 0
}
cmddatalong[1] = jtagarm7tdmi_nop( 0);
cmddatalong[2] = jtagarm7tdmi_nop(systemspeed);
- // write 32-bit instruction code into DR
- cmddatalong[3] = jtagarm7tdmi_instr_primitive(instr, 0);
+ cmddatalong[3] = jtagarm7tdmi_instr_primitive(instr, 0); // write 32-bit instruction code into DR
cmddatalong[4] = jtagarm7tdmi_nop( 0);
cmddatalong[5] = jtagarm7tdmi_nop( 0);
- // inject long
- cmddatalong[6] = jtagarm7tdmi_instr_primitive(parameter, 0);
+ cmddatalong[6] = jtagarm7tdmi_instr_primitive(parameter, 0); // inject long
cmddatalong[7] = jtagarm7tdmi_nop( 0);
cmddatalong[8] = jtagarm7tdmi_nop( 0);
cmddatalong[9] = jtagarm7tdmi_nop( 0);
cmddatalong[1] = jtagarm7tdmi_nop( 0);
cmddatalong[2] = jtagarm7tdmi_nop(systemspeed);
- // write 32-bit instruction code into DR
- cmddatalong[3] = jtagarm7tdmi_instr_primitive(instr, 0);
+ cmddatalong[3] = jtagarm7tdmi_instr_primitive(instr, 0); // write 32-bit instruction code into DR
cmddatalong[4] = jtagarm7tdmi_nop( 0);
cmddatalong[5] = jtagarm7tdmi_nop( 0);
- // inject long
- cmddatalong[6] = jtagarm7tdmi_instr_primitive(parameter, 0);
+ cmddatalong[6] = jtagarm7tdmi_instr_primitive(parameter, 0); // inject long
cmddatalong[7] = jtagarm7tdmi_nop( 0);
retval = jtagarm7tdmi_nop( 0);
cmddatalong[9] = jtagarm7tdmi_nop( 0);
// push nop into pipeline - clean out the pipeline...
cmddatalong[2] = jtagarm7tdmi_nop( 0);
- // push STR_Rx, [R14] into pipeline
- instr = ARM_INSTR_STR_Rx_r14 + ((reg<<12)&0xf00);
+ instr = ARM_READ_REG | (reg<<12); // push STR Rx, [R14] into pipeline
cmddatalong[1] = jtagarm7tdmi_instr_primitive(instr, 0);
- // push nop into pipeline - fetched
- cmddatalong[2] = jtagarm7tdmi_nop( 0);
- // push nop into pipeline - decoded
- cmddatalong[3] = jtagarm7tdmi_nop( 0);
- // push nop into pipeline - executed
- cmddatalong[4] = jtagarm7tdmi_nop( 0);
- // recover 32-bit word
- //retval = jtagarmtransn(0, 32, LSB, END, RETIDLE);
- retval = jtagarm7tdmi_nop( 0);
+ cmddatalong[2] = jtagarm7tdmi_nop( 0); // push nop into pipeline - fetched
+ cmddatalong[3] = jtagarm7tdmi_nop( 0); // push nop into pipeline - decoded
+ cmddatalong[4] = jtagarm7tdmi_nop( 0); // push nop into pipeline - executed
+ retval = jtagarm7tdmi_nop( 0); // recover 32-bit word
cmddatalong[5] = retval;
cmddatalong[6] = jtagarm7tdmi_nop( 0);
cmddatalong[7] = jtagarm7tdmi_nop( 0);
//! Set a 32-bit Register value
unsigned long jtagarm7tdmi_set_register(unsigned char reg, unsigned long val) {
unsigned long retval = 0, instr;
- // push nop into pipeline - clean out the pipeline...
- cmddatalong[2] = jtagarm7tdmi_nop( 0);
+ cmddatalong[2] = jtagarm7tdmi_nop( 0); // push nop into pipeline - clean out the pipeline...
- // push STR_Rx, [R14] into pipeline
- instr = ARM_INSTR_LDR_Rx_r14 + ((reg<<12)&0xf00);
+ instr = ARM_WRITE_REG | (reg<<12); // push LDR Rx, [R14] into pipeline
cmddatalong[1] = jtagarm7tdmi_instr_primitive(instr, 0);
- // push nop into pipeline - fetched
- cmddatalong[2] = jtagarm7tdmi_nop( 0);
- // push nop into pipeline - decoded
- cmddatalong[2] = jtagarm7tdmi_nop( 0);
+ cmddatalong[2] = jtagarm7tdmi_nop( 0); // push nop into pipeline - fetched
+ cmddatalong[3] = jtagarm7tdmi_nop( 0); // push nop into pipeline - decoded
- // push 32-bit word on data bus - execute state
- //retval = jtagarmtransn(val, 32, LSB, END, RETIDLE);
- cmddatalong[3] = jtagarm7tdmi_instr_primitive(val, 0);
- // push nop into pipeline - executed
- cmddatalong[4] = jtagarm7tdmi_nop( 0);
+ cmddatalong[4] = jtagarm7tdmi_instr_primitive(val, 0); // push 32-bit word on data bus - execute state
+ cmddatalong[5] = jtagarm7tdmi_nop( 0); // push nop into pipeline - executed
+
if (reg == ARM_REG_PC){
- cmddatalong[5] = jtagarm7tdmi_nop( 0);
cmddatalong[6] = jtagarm7tdmi_nop( 0);
+ cmddatalong[7] = jtagarm7tdmi_nop( 0);
}
- retval = jtagarm7tdmi_nop( 0);
- cmddatalong[7] = retval;
+ cmddatalong[8] = jtagarm7tdmi_nop( 0);
+
+ retval = cmddatalong[5];
return(retval);
}
unsigned long jtagarm7tdmi_get_regCPSR() {
unsigned long retval = 0;
- // push nop into pipeline - clean out the pipeline...
- cmddatalong[1] = jtagarm7tdmi_nop( 0);
- // push MRS_R0, CPSR into pipeline
- cmddatalong[1] = jtagarm7tdmi_instr_primitive(ARM_INSTR_MRS_R0_CPSR, 0);
- // push nop into pipeline - fetched
- cmddatalong[3] = jtagarm7tdmi_nop( 0);
- // push nop into pipeline - decoded
- cmddatalong[4] = jtagarm7tdmi_nop( 0);
- // push nop into pipeline - executed
- cmddatalong[5] = jtagarm7tdmi_nop( 0);
- // recover 32-bit word
- retval = jtagarm7tdmi_nop( 0);
- cmddatalong[5] = retval;
+ cmddatalong[1] = jtagarm7tdmi_nop( 0); // push nop into pipeline - clean out the pipeline...
+ cmddatalong[2] = jtagarm7tdmi_instr_primitive(ARM_INSTR_MRS_R0_CPSR, 0); // push MRS_R0, CPSR into pipeline
+ cmddatalong[3] = jtagarm7tdmi_nop( 0); // push nop into pipeline - fetched
+ cmddatalong[4] = jtagarm7tdmi_nop( 0); // push nop into pipeline - decoded
+ cmddatalong[5] = jtagarm7tdmi_nop( 0); // push nop into pipeline - executed
+ retval = jtagarm7tdmi_nop( 0); // recover 32-bit word
+ cmddatalong[6] = retval;
return retval;
}
unsigned long jtagarm7tdmi_set_regCPSR(unsigned long val) {
unsigned long retval = 0;
- // push nop into pipeline - clean out the pipeline...
- cmddatalong[1] = jtagarm7tdmi_nop( 0);
- // push MSR cpsr_cxsf, R0 into pipeline
- cmddatalong[1] = jtagarm7tdmi_instr_primitive(ARM_INSTR_MSR_cpsr_cxsf_R0, 0);
- // push nop into pipeline - fetched
- cmddatalong[2] = jtagarm7tdmi_nop( 0);
- // push nop into pipeline - decoded
- cmddatalong[3] = jtagarm7tdmi_nop( 0);
+ cmddatalong[1] = jtagarm7tdmi_nop( 0); // push nop into pipeline - clean out the pipeline...
+ cmddatalong[1] = jtagarm7tdmi_instr_primitive(ARM_INSTR_MSR_cpsr_cxsf_R0, 0); // push MSR cpsr_cxsf, R0 into pipeline
+ cmddatalong[2] = jtagarm7tdmi_nop( 0); // push nop into pipeline - fetched
+ cmddatalong[3] = jtagarm7tdmi_nop( 0); // push nop into pipeline - decoded
- // push 32-bit word on data bus
- retval = jtagarm7tdmi_instr_primitive(val, 0);
- // push nop into pipeline - executed
- cmddatalong[5] = jtagarm7tdmi_nop( 0);
+ retval = jtagarm7tdmi_instr_primitive(val, 0);// push 32-bit word on data bus
+ cmddatalong[5] = jtagarm7tdmi_nop( 0); // push nop into pipeline - executed
cmddatalong[4] = retval;
return(retval);
}
unsigned long jtagarm7tdmi_writemem(unsigned long adr, unsigned long data){
unsigned long r0=0, r1=-1;
- // store R0 and R1
- r0 = jtagarm7tdmi_get_register(0);
+ r0 = jtagarm7tdmi_get_register(0); // store R0 and R1
r1 = jtagarm7tdmi_get_register(1);
- // write address into R0
- jtagarm7tdmi_set_register(0, adr);
- // write data in R1
- jtagarm7tdmi_set_register(1, data);
- //retval = jtagarm7tdmi_exec(ARM_INSTR_LDR_R1_r0_4,1);
- // push nop into pipeline to "clean" it ???
- jtagarm7tdmi_nop( 0);
- // push nop into pipeline with BREAKPT set
- jtagarm7tdmi_nop( 1);
- // push LDR R1, R0, #4 into instruction pipeline
- jtagarm7tdmi_instr_primitive(ARM_INSTR_LDR_R1_r0_4, 0);
- // push nop into pipeline
- jtagarm7tdmi_nop( 0);
- // restore R0 and R1
- jtagarm7tdmi_set_register(1, r1);
+ jtagarm7tdmi_set_register(0, adr); // write address into R0
+ jtagarm7tdmi_set_register(1, data); // write data in R1
+ jtagarm7tdmi_nop( 0); // push nop into pipeline to "clean" it ???
+ jtagarm7tdmi_nop( 1); // push nop into pipeline with BREAKPT set
+ jtagarm7tdmi_instr_primitive(ARM_INSTR_LDR_R1_r0_4, 0); // push LDR R1, R0, #4 into instruction pipeline
+ jtagarm7tdmi_nop( 0); // push nop into pipeline
+ jtagarm7tdmi_set_register(1, r1); // restore R0 and R1
jtagarm7tdmi_set_register(0, r0);
return(-1);
}
+
+
+
//! Read data from address
unsigned long jtagarm7tdmi_readmem(unsigned long adr){
unsigned long retval = 0;
unsigned long r0=0, r1=-1;
int waitcount = 0xfff;
- // select chain 2
- // store R0 and R1 - not yet...
- r0 = jtagarm7tdmi_get_register(0);
+ r0 = jtagarm7tdmi_get_register(0); // store R0 and R1
r1 = jtagarm7tdmi_get_register(1);
- // write address into R0
- jtagarm7tdmi_set_register(0, adr);
- // push nop into pipeline to "clean" it ???
- jtagarm7tdmi_nop( 0);
- // push nop into pipeline with BREAKPT set
- jtagarm7tdmi_nop( 1);
- // push LDR R1, R0, #4 into instruction pipeline
- jtagarm7tdmi_instr_primitive(ARM_INSTR_LDR_R1_r0_4, 0);
- // push nop into pipeline
- jtagarm7tdmi_nop( 0);
- // SHIFT_IR with RESTART instruction
- jtagarm7tdmi_restart();
+ jtagarm7tdmi_set_register(0, adr); // write address into R0
+ jtagarm7tdmi_nop( 0); // push nop into pipeline to "clean" it ???
+ jtagarm7tdmi_nop( 1); // push nop into pipeline with BREAKPT set
+ jtagarm7tdmi_instr_primitive(ARM_INSTR_LDR_R1_r0_4, 0); // push LDR R1, R0, #4 into instruction pipeline
+ jtagarm7tdmi_nop( 0); // push nop into pipeline
+ jtagarm7tdmi_restart(); // SHIFT_IR with RESTART instruction
+
// Poll the Debug Status Register for DBGACK and nMREQ to be HIGH
- while ((jtagarm7tdmi_get_dbgstate() & 1) == 0 && waitcount > 0){
+ while ((jtagarm7tdmi_get_dbgstate() & 9) == 0 && waitcount > 0){
delay(1);
waitcount --;
}
- if (waitcount == 0xffff){
+ if (waitcount == 0){
return (-1);
} else {
- retval = jtagarm7tdmi_get_register(1);
- // read memory value from R1 register
- // restore R0 and R1
- jtagarm7tdmi_set_register(1, r1);
- jtagarm7tdmi_set_register(0, r0);
+ retval = jtagarm7tdmi_get_register(1); // read memory value from R1 register
+ jtagarm7tdmi_set_register(1, r1); // restore R0 and R1
+ jtagarm7tdmi_set_register(0, r0);
}
return retval;
}
int waitcount = 0xfff;
// store watchpoint info? - not right now
- // write 0 in watchpoint 1 address
- eice_write(EICE_WP1ADDR, 0);
- // write 0xffffffff in watchpoint 1 address mask
- eice_write(EICE_WP1ADDRMASK, 0xffffffff);
- // write 0 in watchpoint 1 data
- eice_write(EICE_WP1DATA, 0);
- // write 0xffffffff in watchpoint 1 data mask
- eice_write(EICE_WP1DATAMASK, 0xffffffff);
- // write 0x00000100 in watchpoint 1 control value register (enables watchpoint)
- eice_write(EICE_WP1CTRL, 0x100); //!!!!! WTF! THIS IS SUPPOSED TO BE 9 bits wide?!?
- // write 0xfffffff7 in watchpoint 1 control mask - only detect the fetch instruction
- eice_write(EICE_WP1CTRLMASK, 0xfffffff7); //!!!!! WTF! THIS IS SUPPOSED TO BE 8 bits wide?!?
+ eice_write(EICE_WP1ADDR, 0); // write 0 in watchpoint 1 address
+ eice_write(EICE_WP1ADDRMASK, 0xffffffff); // write 0xffffffff in watchpoint 1 address mask
+ eice_write(EICE_WP1DATA, 0); // write 0 in watchpoint 1 data
+ eice_write(EICE_WP1DATAMASK, 0xffffffff); // write 0xffffffff in watchpoint 1 data mask
+ eice_write(EICE_WP1CTRL, 0x100); //!!!!! WTF! THIS IS SUPPOSED TO BE 9 bits wide?!? // write 0x00000100 in watchpoint 1 control value register (enables watchpoint)
+ eice_write(EICE_WP1CTRLMASK, 0xfffffff7); //!!!!! WTF! THIS IS SUPPOSED TO BE 8 bits wide?!? // write 0xfffffff7 in watchpoint 1 control mask - only detect the fetch instruction
+
// poll until debug status says the cpu is in debug mode
- while (!(jtagarm7tdmi_get_dbgstate() & 0x1) && waitcount > 0){
- delay(5);
- waitcount --;
+ while (!(jtagarm7tdmi_get_dbgstate() & 0x1) && waitcount-- > 0){
+ delay(1);
}
- // write 0 in watchpoint 0 control value - disables watchpoint 0
- eice_write(EICE_WP1CTRL, 0x0);
+ eice_write(EICE_WP1CTRL, 0x0); // write 0 in watchpoint 0 control value - disables watchpoint 0
// store the debug state
last_halt_debug_state = jtagarm7tdmi_get_dbgstate();
- last_halt_pc = jtagarm7tdmi_getpc() - 4; // assume -4 for entering debug mode via watchpoint.
+ last_halt_pc = jtagarm7tdmi_getpc() - 4; // assume -4 for entering debug mode via watchpoint.
count_dbgspd_instr_since_debug = 0;
count_sysspd_instr_since_debug = 0;
- if (last_halt_debug_state & JTAG_ARM7TDMI_DBG_TBIT){
+
+ // get into ARM mode if the T flag is set (Thumb mode)
+ while (jtagarm7tdmi_get_dbgstate() & JTAG_ARM7TDMI_DBG_TBIT && waitcount-- > 0) {
jtagarm7tdmi_setMode_ARM();
}
+ jtagarm7tdmi_resettap();
return waitcount;
}
int waitcount = 0xfff;
unsigned long instr;
// somehow determine what PC should be (a couple ways possible, calculations required)
- // NOP
- jtagarm7tdmi_nop(0);
- // NOP/BREAKPT
- jtagarm7tdmi_nop(1);
+ jtagarm7tdmi_nop(0); // NOP
+ jtagarm7tdmi_nop(1); // NOP/BREAKPT
- if (last_halt_debug_state & JTAG_ARM7TDMI_DBG_TBIT){
- instr = ARM_INSTR_BX_PC + 0x1000000 - (count_dbgspd_instr_since_debug) - (count_sysspd_instr_since_debug*3); //FIXME: make this right - can't we just do an a7solute b/bx?
+ if (last_halt_debug_state & JTAG_ARM7TDMI_DBG_TBIT){ // FIXME: FORNICATED! BX requires register, thus more instrs... could we get away with the same instruction but +1 to offset?
+ instr = ARM_INSTR_B_PC + 0x1000001 - (count_dbgspd_instr_since_debug) - (count_sysspd_instr_since_debug*3); //FIXME: make this right - can't we just do an a7solute b/bx?
jtagarm7tdmi_instr_primitive(instr,0);
} else {
- instr = ARM_INSTR_B_PC + 0x1000000 - (count_dbgspd_instr_since_debug) - (count_sysspd_instr_since_debug*3); //FIXME: make this right - can't we just do an absolute b/bx?
+ instr = ARM_INSTR_B_PC + 0x1000000 - (count_dbgspd_instr_since_debug*4) - (count_sysspd_instr_since_debug*12);
jtagarm7tdmi_instr_primitive(instr,0);
}
- // VERB_RESTART
+
SHIFT_IR;
- jtagarmtransn(ARM7TDMI_IR_RESTART,4,LSB,END,RETIDLE);
+ jtagarmtransn(ARM7TDMI_IR_RESTART,4,LSB,END,RETIDLE); // VERB_RESTART
// wait until restart-bit set in debug state register
while ((jtagarm7tdmi_get_dbgstate() & JTAG_ARM7TDMI_DBG_DBGACK) && waitcount > 0){
- //delay(1);
+ msdelay(1);
waitcount --;
}
last_halt_debug_state = -1;
void jtagarm7tdmihandle(unsigned char app, unsigned char verb, unsigned long len){
register char blocks;
- unsigned int i,val;
+ unsigned int i,val,mlop;
unsigned long at;
jtagarm7tdmi_resettap();
- debugstr("Classic ARM JTAG handler.");
-
- //PLEDOUT^=PLEDPIN;
+
switch(verb){
case START:
//Enter JTAG mode.
cmddatalong[0] = jtagarm7tdmi_start();
- cmddatalong[1] = jtagarm7tdmi_haltcpu();
+ cmddatalong[2] = jtagarm7tdmi_haltcpu();
//jtagarm7tdmi_resettap();
- txdata(app,verb,0x8);
+ cmddatalong[1] = jtagarm7tdmi_get_dbgstate();
+
+ // DEBUG: FIXME: NOT PART OF OPERATIONAL CODE
+ //for (mlop=2;mlop<4;mlop++){
+ // jtagarm7tdmi_set_register(mlop, 0x43424140);
+ //}
+ /////////////////////////////////////////////
+ txdata(app,verb,0xc);
break;
case JTAGARM7TDMI_READMEM:
case PEEK:
jtagarm7tdmi_resettap();
cmddatalong[0] = jtagarm7tdmi_idcode();
txdata(app,verb,4);
- PLEDOUT^=PLEDPIN;
break;
cmddataword[0] = jtagarm7tdmi_exec(cmddataword[0], cmddataword[1], cmddata[9]);
txdata(app,verb,80);
break;
- case JTAGARM7TDMI_STEP_INSTR:
+ //case JTAGARM7TDMI_STEP_INSTR:
/* case JTAGARM7TDMI_READ_CODE_MEMORY:
case JTAGARM7TDMI_WRITE_FLASH_PAGE:
case JTAGARM7TDMI_READ_FLASH_PAGE:
cmddatalong[9] = jtagarmtransn(0x44444444, 1, MSB, NOEND, NORETIDLE);
cmddatalong[10] = jtagarmtransn(cmddatalong[8], 32, MSB, NOEND, NORETIDLE);
cmddatalong[11] = jtagarmtransn(cmddatalong[9], 1, MSB, END, RETIDLE);
+ jtagarm7tdmi_resettap();
txdata(app,verb,48);
break;