X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=firmware%2Fapps%2Fjtag%2Fjtagarm7.c;h=2a1642119736d730d63fbc72d30286bbd10b2dde;hp=7e103fcc4c22195319604160cef9dbcdda5ba9a8;hb=f7fdc48f01ada713d5034763a2f3395fe2a7c51b;hpb=c3c1c0c873f693e6d57e8e2acf11d52aa6540ff3 diff --git a/firmware/apps/jtag/jtagarm7.c b/firmware/apps/jtag/jtagarm7.c index 7e103fc..2a16421 100644 --- a/firmware/apps/jtag/jtagarm7.c +++ b/firmware/apps/jtag/jtagarm7.c @@ -4,8 +4,38 @@ #include "platform.h" #include "command.h" +#include "jtag.h" #include "jtagarm7.h" +//! Handles ARM7TDMI JTAG commands. Forwards others to JTAG. +void jtagarm7_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len); + +// define the jtagarm7 app's app_t +app_t const jtagarm7_app = { + + /* app number */ + JTAGARM7, + + /* handle fn */ + jtagarm7_handle_fn, + + /* name */ + "JTAGARM7", + + /* desc */ + "\tThe JTAGARM7 app extends the basic JTAG app with support\n" + "\tfor JTAG'ing ARM7TDMI based devices.\n" +}; + +unsigned long last_instr = -1; +unsigned char last_sysstate = 0; +unsigned char last_ir = -1; +unsigned char last_scanchain = -1; +unsigned char current_dbgstate = -1; +//unsigned char last_halt_debug_state = -1; +//unsigned long last_halt_pc = -1; /**** 20-pin Connection Information (pin1 is on top-right for both connectors)**** GoodFET -> 7TDMI 20-pin connector (HE-10 connector) @@ -49,18 +79,18 @@ http://hri.sourceforge.net/tools/jtag_faq_org.html // ! Start JTAG, setup pins, reset TAP and return IDCODE void jtagarm7tdmi_start() { - jtagsetup(); + jtag_setup(); SETTST; - jtag_resettap(); + jtag_reset_tap(); } u8 jtagarm_shift_ir(u8 ir, u8 flags){ u8 retval = 0; if (last_ir != ir){ - jtag_goto_shift_ir(); - retval = jtagtransn(ir, 4, LSB|flags); - tapstate = RunTest_Idle; + jtag_capture_ir(); + jtag_shift_register(); + retval = jtag_trans_n(ir, 4, LSB|flags); last_ir = ir; } return retval; @@ -78,9 +108,9 @@ state” to the “Select DR” state each time the “Update” state is reache if (last_scanchain != chain){ jtagarm_shift_ir(ARM7TDMI_IR_SCAN_N, NORETIDLE); last_scanchain = chain; - jtag_goto_shift_dr(); - retval = jtagtransn(chain, 4, LSB | NORETIDLE); - tapstate = Update_DR; + jtag_capture_dr(); + jtag_shift_register(); + retval = jtag_trans_n(chain, 4, LSB | NORETIDLE); } jtagarm_shift_ir(testmode, NORETIDLE); return(retval); @@ -92,11 +122,11 @@ state” to the “Select DR” state each time the “Update” state is reache unsigned long eice_write(unsigned char reg, unsigned long data){ unsigned long retval, temp; jtagarm7tdmi_scan(2, ARM7TDMI_IR_INTEST); - jtag_goto_shift_dr(); - retval = jtagtransn(data, 32, LSB| NOEND| NORETIDLE); // send in the data - 32-bits lsb - temp = jtagtransn(reg, 5, LSB| NOEND| NORETIDLE); // send in the register address - 5 bits lsb - jtagtransn(1, 1, LSB); // send in the WRITE bit - tapstate = RunTest_Idle; + jtag_capture_dr(); + jtag_shift_register(); + retval = jtag_trans_n(data, 32, LSB| NOEND| NORETIDLE); // send in the data - 32-bits lsb + temp = jtag_trans_n(reg, 5, LSB| NOEND| NORETIDLE); // send in the register address - 5 bits lsb + jtag_trans_n(1, 1, LSB); // send in the WRITE bit return(retval); } @@ -104,12 +134,13 @@ unsigned long eice_write(unsigned char reg, unsigned long data){ unsigned long eice_read(unsigned char reg){ // PROVEN unsigned long temp, retval; jtagarm7tdmi_scan(2, ARM7TDMI_IR_INTEST); - jtag_goto_shift_dr(); // send in the register address - 5 bits LSB - temp = jtagtransn(reg, 5, LSB| NOEND| NORETIDLE); - jtagtransn(0L, 1, LSB); // clear TDI to select "read only" - jtag_goto_shift_dr(); // Now shift out the 32 bits - retval = jtagtransn(0L, 32, LSB); // atmel arm jtag docs pp.10-11: LSB first - tapstate = RunTest_Idle; + jtag_capture_dr(); + jtag_shift_register(); // send in the register address - 5 bits LSB + temp = jtag_trans_n(reg, 5, LSB| NOEND| NORETIDLE); + jtag_trans_n(0L, 1, LSB); // clear TDI to select "read only" + jtag_capture_dr(); + jtag_shift_register(); // Now shift out the 32 bits + retval = jtag_trans_n(0L, 32, LSB); // atmel arm jtag docs pp.10-11: LSB first return(retval); } @@ -117,14 +148,19 @@ unsigned long eice_read(unsigned char reg){ // PROVEN //! push an instruction into the pipeline unsigned long jtagarm7tdmi_instr_primitive(unsigned long instr, char breakpt){ // PROVEN unsigned long retval = 0; + //debugstr("jtagarm7tdmi_instr_primitive"); jtagarm7tdmi_scan(1, ARM7TDMI_IR_INTEST); + //debugstr("instruction:"); //debughex32(instr); - if (last_instr != instr && last_sysstate != breakpt){ - jtag_goto_shift_dr(); + //if (!(last_instr == instr && last_sysstate == breakpt)) + { + jtag_capture_dr(); + jtag_shift_register(); // if the next instruction is to run using MCLK (master clock), set TDI if (breakpt) { + //debugstr("--breakpt flag set"); SETMOSI; } else @@ -134,17 +170,21 @@ unsigned long jtagarm7tdmi_instr_primitive(unsigned long instr, char breakpt){ jtag_tcktock(); // Now shift in the 32 bits - retval = jtagtransn(instr, 32, 0); // Must return to RUN-TEST/IDLE state for instruction to enter pipeline, and causes debug clock. - tapstate = RunTest_Idle; + retval = jtag_trans_n(instr, 32, 0); // Must return to RUN-TEST/IDLE state for instruction to enter pipeline, and causes debug clock. + //debugstr("hot off the pipeline!"); + //debughex32(retval); last_instr = instr; last_sysstate = breakpt; - } else - jtag_tcktock(); + }// else + //{ // this assumes we don't want retval! wtfo!? + // jtag_tcktock(); + //} return(retval); } u32 jtagarm7tdmi_nop(u8 brkpt){ // WARNING: current_dbgstate must be up-to-date before calling this function!!!!! + //debugstr("jtagarm7tdmi_nop"); if (current_dbgstate & JTAG_ARM7TDMI_DBG_TBIT) return jtagarm7tdmi_instr_primitive(THUMB_INSTR_NOP, brkpt); return jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, brkpt); @@ -154,6 +194,7 @@ u32 jtagarm7tdmi_nop(u8 brkpt){ //! Retrieve a 32-bit Register value unsigned long jtagarm7_get_reg_prim(unsigned long instr){ + //debugstr("jtagarm7_get_reg_prim"); jtagarm7tdmi_nop( 0); jtagarm7tdmi_instr_primitive(instr, 0); jtagarm7tdmi_nop( 0); @@ -183,10 +224,8 @@ void jtagarm7_thumb_swap_reg(unsigned char dir, unsigned long reg){ jtagarm7tdmi_nop( 0); if (dir){ jtagarm7tdmi_instr_primitive((unsigned long)(THUMB_INSTR_MOV_LoHi | (reg) | (reg<<16)), 0); - //debughex32((unsigned long)(THUMB_INSTR_MOV_LoHi | (reg) | (reg<<16))); } else { jtagarm7tdmi_instr_primitive((unsigned long)(THUMB_INSTR_MOV_HiLo | (reg<<3) | (reg<<19)), 0); - //debughex32((unsigned long)(THUMB_INSTR_MOV_HiLo | (reg<<3) | (reg<<19))); } jtagarm7tdmi_nop( 0); jtagarm7tdmi_nop( 0); @@ -196,6 +235,9 @@ void jtagarm7_thumb_swap_reg(unsigned char dir, unsigned long reg){ unsigned long jtagarm7tdmi_get_register(unsigned long reg) { // PROVEN - 100827 unsigned long retval=0L, instr, r0; current_dbgstate = eice_read(EICE_DBGSTATUS); + //debugstr("current_dbgstate:"); + //debughex32(current_dbgstate); + if (current_dbgstate & JTAG_ARM7TDMI_DBG_TBIT){ if (reg > 7){ //debugstr("debug: jtagarm7tdmi_get_register: thumb reg > 15"); @@ -206,10 +248,14 @@ unsigned long jtagarm7tdmi_get_register(unsigned long reg) { jtagarm7_set_reg_prim( THUMB_WRITE_REG, 0, r0); // restore r0 return retval; } else { + //debugstr("debug: jtagarm7tdmi_get_register: thumb reg < 15"); instr = (unsigned long)(THUMB_READ_REG | (unsigned long)reg | (unsigned long)(reg<<16L)); } } else + { + //debugstr("debug: jtagarm7tdmi_get_register: arm"); instr = (reg<<12L) | ARM_READ_REG; // STR Rx, [R14] + } return jtagarm7_get_reg_prim(instr); } @@ -246,7 +292,10 @@ void jtagarm7tdmi_set_register(unsigned long reg, unsigned long val) { /////////////////////////////////////////////////////////////////////////////////////////////////// //! Handles ARM7TDMI JTAG commands. Forwards others to JTAG. -void jtagarm7tdmihandle(unsigned char app, unsigned char verb, unsigned long len){ +void jtagarm7_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len) +{ unsigned int val; switch(verb){ @@ -260,23 +309,52 @@ void jtagarm7tdmihandle(unsigned char app, unsigned char verb, unsigned long len txdata(app,verb,1); break; case JTAG_DR_SHIFT: - jtag_goto_shift_dr(); - cmddatalong[0] = jtagtransn(cmddatalong[1],cmddata[0],cmddata[1]); - tapstate = (cmddata[1]&NORETIDLE)>0?Update_DR:RunTest_Idle; - txdata(app,verb,4); + jtag_capture_dr(); + jtag_shift_register(); + val = cmddata[0]; + if (cmddata[0] > 32) + { + debughex32(cmddatalong[0]); + debughex32(cmddatalong[1]); + cmddatalong[1] = jtag_trans_n(cmddatalong[2], val - 32 ,cmddata[1] | NOEND |NORETIDLE); + cmddatalong[0] = jtag_trans_n(cmddatalong[2], 32, cmddata[1]); + } + else + { + debughex32(cmddatalong[0]); + cmddatalong[0] = jtag_trans_n(cmddatalong[1], val, cmddata[1]); + } + txdata(app,verb,val/8); + break; + case JTAG_DR_SHIFT_MORE: + // assumes you just executed JTAG_DR_SHIFT with NOEND flag set + val = cmddata[0]; + if (cmddata[0] > 32) + { + debughex32(cmddatalong[0]); + debughex32(cmddatalong[1]); + cmddatalong[1] = jtag_trans_n(cmddatalong[2], val - 32 ,cmddata[1] | NOEND |NORETIDLE); + cmddatalong[0] = jtag_trans_n(cmddatalong[2], 32, cmddata[1]); + } + else + { + debughex32(cmddatalong[0]); + cmddatalong[0] = jtag_trans_n(cmddatalong[1], val, cmddata[1]); + } + txdata(app,verb,val/8); break; case JTAGARM7_CHAIN0: jtagarm7tdmi_scan(0, ARM7TDMI_IR_INTEST); - jtag_goto_shift_dr(); + jtag_capture_dr(); + jtag_shift_register(); //debughex32(cmddatalong[0]); //debughex(cmddataword[4]); //debughex32(cmddatalong[1]); //debughex32(cmddatalong[3]); - cmddatalong[0] = jtagtransn(cmddatalong[0], 32, LSB| NOEND| NORETIDLE); - cmddatalong[2] = jtagtransn(cmddataword[4], 9, MSB| NOEND| NORETIDLE); - cmddatalong[1] = jtagtransn(cmddatalong[1], 32, MSB| NOEND| NORETIDLE); - cmddatalong[3] = jtagtransn(cmddatalong[3], 32, MSB); - tapstate = RunTest_Idle; + cmddatalong[0] = jtag_trans_n(cmddatalong[0], 32, LSB| NOEND| NORETIDLE); + cmddatalong[2] = jtag_trans_n(cmddataword[4], 9, MSB| NOEND| NORETIDLE); + cmddatalong[1] = jtag_trans_n(cmddatalong[1], 32, MSB| NOEND| NORETIDLE); + cmddatalong[3] = jtag_trans_n(cmddatalong[3], 32, MSB); txdata(app,verb,16); break; case JTAGARM7_SCANCHAIN1: @@ -301,12 +379,12 @@ void jtagarm7tdmihandle(unsigned char app, unsigned char verb, unsigned long len jtagarm7tdmi_set_register(cmddatalong[1], cmddatalong[0]); txdata(app,verb,4); break; - case JTAG_RESETTARGET: + case JTAG_RESET_TARGET: //FIXME: BORKEN debugstr("RESET TARGET"); - CLRTST; + CLRRST; delay(cmddataword[0]); - SETTST; + SETRST; txdata(app,verb,4); break; @@ -321,7 +399,7 @@ void jtagarm7tdmihandle(unsigned char app, unsigned char verb, unsigned long len case JTAGARM7_CHIP_ERASE: */ default: - jtaghandle(app,verb,len); + (*(jtag_app.handle))(app,verb,len); } }