Glitching index on vcc.
[goodfet] / firmware / apps / jtag / jtagarm7tdmi.c
1 /*! \file jtagarm7tdmi.c
2   \author Matthew Carpenter <matt@inguardians.com>
3   \brief ARM7TDMI JTAG (AT91R40008)
4 */
5
6 #include "platform.h"
7 #include "command.h"
8 #include "jtag.h"
9 #include "jtagarm7tdmi.h"
10
11
12 /**** 20-pin Connection Information (pin1 is on top-right for both connectors)****
13 GoodFET  ->  7TDMI 20-pin connector (HE-10 connector)
14   1               13 (TDO)
15   2               1  (Vdd)
16   3               5  (TDI)
17   5               7  (TMS)
18   7               9  (TCK)
19   8               15 (nRST)
20   9               4,6,8,10,12,14,16,18,20 (GND)
21   11              17/3 (nTRST)  (different sources suggest 17 or 3 alternately)
22 ********************************/
23
24 /**** 14-pin Connection Information (pin1 is on top-right for both connectors)****
25 GoodFET  ->  7TDMI 14-pin connector
26   1               11 (TDO)
27   2               1  (Vdd)
28   3               5  (TDI)
29   5               7  (TMS)
30   7               9  (TCK)
31   8               12 (nRST)
32   9               2,4,6,8,10,14 (GND)
33   11              3 (nTRST)
34
35 http://hri.sourceforge.net/tools/jtag_faq_org.html
36 ********************************/
37
38 /****************************************************************
39 Enabling jtag likely differs with most platforms.  We will attempt to enable most from here.  Override jtagarm7tdmi_start() to extend for other implementations
40 ARM7TDMI enables three different scan chains:
41     * Chain0 - "entire periphery" including data bus
42     * Chain1 - core data bus (subset of Chain0)  - Instruction Pipeline
43     * Chain2 - EmbeddedICE Logic Registers - This is our way into the fun stuff.
44     
45
46 ---
47 You can disable EmbeddedICE-RT by setting the DBGEN input LOW.
48 Caution
49 Hard wiring the DBGEN input LOW permanently disables all debug functionality.
50 When DBGEN is LOW, it inhibits DBGDEWPT, DBGIEBKPT, and EDBGRQ to
51 the core, and DBGACK from the ARM9E-S core is always LOW.
52 ---
53
54
55 ---
56 When the ARM9E-S core is in debug state, you can examine the core and system state
57 by forcing the load and store multiples into the instruction pipeline.
58 Before you can examine the core and system state, the debugger must determine
59 whether the processor entered debug from Thumb state or ARM state, by examining
60 bit 4 of the EmbeddedICE-RT debug status register. If bit 4 is HIGH, the core has
61 entered debug from Thumb state.
62 For more details about determining the core state, see Determining the core and system
63 state on page B-18.
64 ---
65
66
67 --- olimex - http://www.olimex.com/dev/pdf/arm-jtag.pdf
68 JTAG signals description:
69 PIN.1 (VTREF) Target voltage sense. Used to indicate the target’s operating voltage to thedebug tool.
70 PIN.2 (VTARGET) Target voltage. May be used to supply power to the debug tool.
71 PIN.3 (nTRST) JTAG TAP reset, this signal should be pulled up to Vcc in target board.
72 PIN4,6, 8, 10,12,14,16,18,20 Ground. The Gnd-Signal-Gnd-Signal strategy implemented on the 20-way connection scheme improves noiseimmunity on the target connect cable.
73 *PIN.5 (TDI) JTAG serial data in, should be pulled up to Vcc on target board.
74 *PIN.7 (TMS) JTAG TAP Mode Select, should be pulled up to Vcc on target board.
75 *PIN.9 (TCK) JTAG clock.
76 PIN.11 (RTCK) JTAG retimed clock.Implemented on certain ASIC ARM implementations the host ASIC may need to synchronize external inputs (such as JTAG inputs) with its own internal clock.
77 *PIN.13 (TDO) JTAG serial data out.
78 *PIN.15 (nSRST) Target system reset.
79 *PIN.17 (DBGRQ) Asynchronous debug request.  DBGRQ allows an external signal to force the ARM core into debug mode, should be pull down to GND.
80 PIN.19 (DBGACK) Debug acknowledge. The ARM core acknowledges debug-mode inresponse to a DBGRQ input.
81
82 ****************************************************************/
83
84
85 /************************** JTAGARM7TDMI Primitives ****************************/
86 void jtag_goto_shift_ir() {
87   SETTMS;
88   jtag_arm_tcktock();
89   jtag_arm_tcktock();
90   CLRTMS;
91   jtag_arm_tcktock();
92   jtag_arm_tcktock();
93
94 }
95
96 void jtag_goto_shift_dr() {
97   SETTMS;
98   jtag_arm_tcktock();
99   CLRTMS;
100   jtag_arm_tcktock();
101   jtag_arm_tcktock();
102 }
103
104 void jtag_reset_to_runtest_idle() {
105   SETTMS;
106   jtag_arm_tcktock();
107   jtag_arm_tcktock();
108   jtag_arm_tcktock();
109   jtag_arm_tcktock();
110   jtag_arm_tcktock();  // now in Reset state
111   CLRTMS;
112   jtag_arm_tcktock();  // now in Run-Test/Idle state
113 }
114
115 void jtag_arm_tcktock() {
116   CLRTCK; 
117   PLEDOUT^=PLEDPIN; 
118   delay(5);
119   SETTCK; 
120   PLEDOUT^=PLEDPIN;
121 }
122
123 // ! Start JTAG, setup pins, reset TAP and return IDCODE
124 unsigned long jtagarm7tdmi_start() {
125   jtagsetup();
126   //Known-good starting position.
127   //Might be unnecessary.
128   SETTST;
129   SETRST;
130   
131   delay(0xFF);
132   
133   //Entry sequence from Page 67 of SLAU265A for 4-wire JTAG
134   CLRRST;
135   delay(20);
136   CLRTST;
137
138   msdelay(10);
139   SETRST;
140   /*
141   P5DIR &=~RST;
142   */
143   delay(0xFF);
144   jtagarm7tdmi_resettap();
145   current_chain = 3;
146   return jtagarm7tdmi_idcode();
147 }
148
149
150 //! Reset TAP State Machine       
151 void jtagarm7tdmi_resettap(){               // PROVEN
152   jtag_reset_to_runtest_idle();
153 }
154
155 //! Shift N bits over TDI/TDO.  May choose LSB or MSB, and select whether to terminate (TMS-high on last bit) and whether to return to RUNTEST/IDLE
156 unsigned long jtagarmtransn(unsigned long word, unsigned char bitcount, unsigned char lsb, unsigned char end, unsigned char retidle){               // PROVEN
157   unsigned int bit;
158   unsigned long high = 1;
159   unsigned long mask;
160
161   for (bit=(bitcount-1)/8; bit>0; bit--)
162     high <<= 8;
163   high <<= ((bitcount-1)%8);
164
165   mask = high-1;
166
167   if (lsb) {
168     for (bit = bitcount; bit > 0; bit--) {
169       /* write MOSI on trailing edge of previous clock */
170       if (word & 1)
171         {SETMOSI;}
172       else
173         {CLRMOSI;}
174       word >>= 1;
175
176       if (bit==1 && end)
177         SETTMS;//TMS high on last bit to exit.
178        
179       jtag_arm_tcktock();
180
181       /* read MISO on trailing edge */
182       if (READMISO){
183         word += (high);
184       }
185     }
186   } else {
187     for (bit=bitcount; bit>0; bit++) {
188       /* write MOSI on trailing edge of previous clock */
189       if (word & high)
190         {SETMOSI;}
191       else
192         {CLRMOSI;}
193       word = (word & mask) << 1;
194
195       if (bit==1 && end)
196         SETTMS;//TMS high on last bit to exit.
197
198       jtag_arm_tcktock();
199
200       /* read MISO on trailing edge */
201       word |= READMISO;
202     }
203   }
204
205   if (end){
206     // exit state
207     jtag_arm_tcktock();
208     // update state
209     if (retidle){
210       CLRTMS;
211       jtag_arm_tcktock();
212     }
213   }
214   return word;
215 }
216
217
218
219 //! push an instruction into the pipeline  - Assumes scan-chain 1 is already INTEST
220 unsigned long jtagarm7tdmi_instr_primitive(unsigned long instr, char breakpt){               // PROVEN
221   unsigned long retval;
222   SHIFT_DR;
223   // if the next instruction is to run using MCLK (master clock), set TDI
224   if (breakpt)
225     {
226     SETMOSI;
227     count_sysspd_instr_since_debug++;
228     } 
229   else
230     {
231     CLRMOSI; 
232     count_dbgspd_instr_since_debug++;
233     }
234
235   jtag_arm_tcktock();
236   
237   // Now shift in the 32 bits
238   retval = jtagarmtransn(instr, 32, MSB, END, RETIDLE);    // Must return to RUN-TEST/IDLE state for instruction to enter pipeline, and causes debug clock.
239   jtag_arm_tcktock();
240   return(retval);
241   
242 }
243
244 /*    stolen from ARM DDI0029G documentation, translated using ARM Architecture Reference Manual (14128.pdf)
245 STR R0, [R0]; Save R0 before use
246 MOV R0, PC ; Copy PC into R0
247 STR R0, [R0]; Now save the PC in R0
248 BX PC ; Jump into ARM state
249 MOV R8, R8 ;
250 MOV R8, R8 ;
251 NOP
252 NOP
253
254 */
255 //! set the current mode to ARM, returns PC (FIXME).  Should be used by haltcpu(), which should also store PC and the THUMB state, for use by releasecpu();
256 unsigned long jtagarm7tdmi_setMode_ARM(){               // PROVEN
257   unsigned long retval = 0xff;
258   while ((jtagarm7tdmi_get_dbgstate() & JTAG_ARM7TDMI_DBG_TBIT)&& retval-- > 0){
259     jtagarm7tdmi_scan_intest(1);
260     cmddataword[1] = jtagarm7tdmi_instr_primitive(THUMB_INSTR_STR_R0_r0,0);
261     cmddataword[2] = jtagarm7tdmi_instr_primitive(THUMB_INSTR_MOV_R0_PC,0);
262     cmddataword[3] = jtagarm7tdmi_instr_primitive(THUMB_INSTR_STR_R0_r0,0);
263     cmddataword[4] = jtagarm7tdmi_instr_primitive(THUMB_INSTR_BX_PC,0);
264     cmddataword[5] = jtagarm7tdmi_instr_primitive(THUMB_INSTR_NOP,0);
265     cmddataword[6] = jtagarm7tdmi_instr_primitive(THUMB_INSTR_NOP,0);
266     delay(10);
267   }
268   return(retval);
269 }
270
271
272
273
274 /************************* EmbeddedICE Primitives ****************************/
275 //! shifter for writing to chain2 (EmbeddedICE). 
276 unsigned long eice_write(unsigned char reg, unsigned long data){
277   unsigned long retval, temp;
278   jtagarm7tdmi_scan_intest(2);
279   // Now shift in the 32 bits
280   SHIFT_DR;
281   retval = jtagarmtransn(data, 32, LSB, NOEND, NORETIDLE);          // send in the data - 32-bits lsb
282   temp = jtagarmtransn(reg, 5, LSB, NOEND, NORETIDLE);              // send in the register address - 5 bits lsb
283   jtagarmtransn(1, 1, LSB, END, RETIDLE);              // send in the register address - 5 bits lsb
284   
285   //SETTMS;   // Last Bit - Exit UPDATE_DR
286   //// is this update a read/write or just read?
287   //SETMOSI;
288   //jtag_arm_tcktock();
289   
290   return(retval); 
291 }
292
293 //! shifter for reading from chain2 (EmbeddedICE).
294 unsigned long eice_read(unsigned char reg){               // PROVEN
295   unsigned long temp;
296   jtagarm7tdmi_scan_intest(2);
297
298   // send in the register address - 5 bits LSB
299   SHIFT_DR;
300   temp = jtagarmtransn(reg, 5, LSB, NOEND, NORETIDLE);
301   
302   // clear TDI to select "read only"
303   jtagarmtransn(0, 1, LSB, END, RETIDLE);
304   
305   SHIFT_DR;
306   // Now shift out the 32 bits
307   return(jtagarmtransn(0, 32, LSB, END, RETIDLE));   // atmel arm jtag docs pp.10-11: LSB first
308   
309 }
310
311
312
313
314 /************************************************************************
315 * ARM7TDMI core has 6 primary registers to be connected between TDI/TDO
316 *   * Bypass Register
317 *   * ID Code Register
318 *   * Scan Chain Select Register    (4 bits_lsb)
319 *   * Scan Chain 0                  (64+* bits: 32_databits_lsb + ctrlbits + 32_addrbits_msb)
320 *   * Scan Chain 1                  (33 bits: 32_bits + BREAKPT)
321 *   * Scan Chain 2                  (38 bits: rw + 5_regbits_msb + 32_databits_msb)
322 ************************************************************************/
323
324
325
326 /************************** Basic JTAG Verb Commands *******************************/
327 //! Grab the core ID.
328 unsigned long jtagarm7tdmi_idcode(){               // PROVEN
329   SHIFT_IR;
330   jtagarmtransn(ARM7TDMI_IR_IDCODE, 4, LSB, END, RETIDLE);
331   SHIFT_DR;
332   return jtagarmtransn(0,32, LSB, END, RETIDLE);
333 }
334
335 //!  Connect Bypass Register to TDO/TDI
336 unsigned char jtagarm7tdmi_bypass(){               // PROVEN
337   SHIFT_IR;
338   return jtagarmtransn(ARM7TDMI_IR_BYPASS, 4, LSB, END, NORETIDLE);
339 }
340 //!  INTEST verb - do internal test
341 unsigned char jtagarm7tdmi_intest() { 
342   SHIFT_IR;
343   return jtagarmtransn(ARM7TDMI_IR_INTEST, 4, LSB, END, NORETIDLE); 
344 }
345
346 //!  EXTEST verb
347 unsigned char jtagarm7tdmi_extest() { 
348   SHIFT_IR;
349   return jtagarmtransn(ARM7TDMI_IR_EXTEST, 4, LSB, END, NORETIDLE);
350 }
351
352 //!  SAMPLE verb
353 //unsigned long jtagarm7tdmi_sample() { 
354 //  jtagarm7tdmi_ir_shift4(ARM7TDMI_IR_SAMPLE);        // ???? same here.
355 //  return jtagtransn(0,32);
356 //}
357
358 //!  RESTART verb
359 unsigned char jtagarm7tdmi_restart() { 
360   SHIFT_IR;
361   return jtagarmtransn(ARM7TDMI_IR_RESTART, 4, LSB, END, RETIDLE); 
362 }
363
364 //!  ARM7TDMI_IR_CLAMP               0x5
365 unsigned long jtagarm7tdmi_clamp() { 
366   SHIFT_IR;
367   jtagarmtransn(ARM7TDMI_IR_CLAMP, 4, LSB, END, NORETIDLE);
368   SHIFT_DR;
369   return jtagarmtransn(0, 32, LSB, END, RETIDLE);
370 }
371
372 //!  ARM7TDMI_IR_HIGHZ               0x7
373 unsigned char jtagarm7tdmi_highz() { 
374   SHIFT_IR;
375   return jtagarmtransn(ARM7TDMI_IR_HIGHZ, 4, LSB, END, NORETIDLE);
376 }
377
378 //! define ARM7TDMI_IR_CLAMPZ              0x9
379 unsigned char jtagarm7tdmi_clampz() { 
380   SHIFT_IR;
381   return jtagarmtransn(ARM7TDMI_IR_CLAMPZ, 4, LSB, END, NORETIDLE);
382 }
383
384
385 //!  Connect the appropriate scan chain to TDO/TDI.  SCAN_N, INTEST, ENDS IN SHIFT_DR!!!!!
386 unsigned long jtagarm7tdmi_scan_intest(int chain) {               // PROVEN
387   unsigned long retval;
388   if (current_chain == chain)
389     return current_chain;
390   jtagarm7tdmi_resettap();  // assumed already sane?
391   SHIFT_IR;
392   jtagarmtransn(ARM7TDMI_IR_SCAN_N, 4, LSB, END, NORETIDLE);
393   SHIFT_DR;
394   retval = jtagarmtransn(chain, 4, LSB, END, NORETIDLE);
395   current_chain = chain;
396   jtagarm7tdmi_intest();
397   //SHIFT_DR;
398   return(retval);
399 }
400
401
402
403
404 /************************* ICEBreaker/EmbeddedICE Stuff ******************************/
405 //! Grab debug register
406 unsigned long jtagarm7tdmi_get_dbgstate() {       // ICE Debug register, *NOT* ARM register DSCR    //    PROVEN
407   jtagarm7tdmi_resettap();
408   jtagarm7tdmi_scan_intest(2);                         // select ICEBreaker
409   return eice_read(EICE_DBGSTATUS);
410 }
411
412 //! Grab debug register
413 unsigned long jtagarm7tdmi_get_dbgctrl() {
414   jtagarm7tdmi_resettap();
415   jtagarm7tdmi_scan_intest(2);                        // select ICEBreaker
416   return eice_read(EICE_DBGCTRL);
417 }
418
419 //! Update debug register
420 unsigned long jtagarm7tdmi_set_dbgctrl(unsigned long bits) {
421   jtagarm7tdmi_resettap();
422   jtagarm7tdmi_scan_intest(2);                        // select ICEBreaker
423   return eice_write(EICE_DBGCTRL, bits);
424 }
425
426
427
428 //!  Set and Enable Watchpoint 0
429 void jtagarm7tdmi_set_watchpoint0(unsigned long addr, unsigned long addrmask, unsigned long data, unsigned long datamask, unsigned long ctrl, unsigned long ctrlmask){
430   // select ICEBreaker
431   jtagarm7tdmi_scan_intest(2);
432   // store watchpoint info?  - not right now
433   // write 0 in watchpoint 0 address
434   eice_write(EICE_WP0ADDR, addr);
435   // write 0xffffffff in watchpoint 0 address mask
436   eice_write(EICE_WP0ADDRMASK, addrmask);
437   // write 0 in watchpoint 0 data
438   eice_write(EICE_WP0DATA, data);
439   // write 0xffffffff in watchpoint 0 data mask
440   eice_write(EICE_WP0DATAMASK, datamask);
441   // write 0x00000100 in watchpoint 0 control value register (enables watchpoint)
442   eice_write(EICE_WP0CTRL, ctrlmask);
443   // write 0xfffffff7 in watchpoint 0 control mask - only detect the fetch instruction
444   eice_write(EICE_WP0CTRLMASK, ctrlmask);
445 }
446
447 //!  Set and Enable Watchpoint 1
448 void jtagarm7tdmi_set_watchpoint1(unsigned long addr, unsigned long addrmask, unsigned long data, unsigned long datamask, unsigned long ctrl, unsigned long ctrlmask){
449   // select ICEBreaker
450   jtagarm7tdmi_scan_intest(2);
451   // store watchpoint info?  - not right now
452   // write 0 in watchpoint 1 address
453   eice_write(EICE_WP1ADDR, addr);
454   // write 0xffffffff in watchpoint 1 address mask
455   eice_write(EICE_WP1ADDRMASK, addrmask);
456   // write 0 in watchpoint 1 data
457   eice_write(EICE_WP1DATA, data);
458   // write 0xffffffff in watchpoint 1 data mask
459   eice_write(EICE_WP1DATAMASK, datamask);
460   // write 0x00000100 in watchpoint 1 control value register (enables watchpoint)
461   eice_write(EICE_WP1CTRL, ctrl);
462   // write 0xfffffff7 in watchpoint 1 control mask - only detect the fetch instruction
463   eice_write(EICE_WP1CTRLMASK, ctrlmask);
464 }
465
466 //!  Disable Watchpoint 0
467 void jtagarm7tdmi_disable_watchpoint0(){
468   // select ICEBreaker
469   jtagarm7tdmi_scan_intest(2);
470   // write 0 in watchpoint 0 control value - disables watchpoint 0
471   eice_write(EICE_WP0CTRL, 0x0);
472 }
473   
474 //!  Disable Watchpoint 1
475 void jtagarm7tdmi_disable_watchpoint1(){
476   // select ICEBreaker
477   jtagarm7tdmi_scan_intest(2);
478   // write 0 in watchpoint 0 control value - disables watchpoint 0
479   eice_write(EICE_WP1CTRL, 0x0);
480 }
481
482
483
484 /******************** Complex Commands **************************/
485 //! Push an instruction into the CPU pipeline
486 //  NOTE!  Must provide EXECNOPARM for parameter if no parm is required.
487 unsigned long test_exec(unsigned long instr, unsigned long parameter, unsigned char systemspeed) {
488   unsigned long retval;
489   // select chain 1
490   jtagarm7tdmi_scan_intest(1);
491
492   cmddatalong[1] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
493   cmddatalong[2] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP,systemspeed);
494   // write 32-bit instruction code into DR
495   cmddatalong[3] = jtagarm7tdmi_instr_primitive(instr, 0);
496   cmddatalong[4] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
497   cmddatalong[5] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
498   // inject long
499   cmddatalong[6] = jtagarm7tdmi_instr_primitive(parameter, 0);
500   cmddatalong[7] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
501   cmddatalong[8] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
502   cmddatalong[9] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
503   retval = cmddatalong[9];
504
505   return(retval);
506 }
507
508
509 //! Push an instruction into the CPU pipeline
510 //  NOTE!  Must provide EXECNOPARM for parameter if no parm is required.
511 unsigned long jtagarm7tdmi_exec(unsigned long instr, unsigned long parameter, unsigned char systemspeed) {
512   unsigned long retval;
513   // select chain 1
514   jtagarm7tdmi_scan_intest(1);
515
516   cmddatalong[1] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
517   cmddatalong[2] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP,systemspeed);
518   // write 32-bit instruction code into DR
519   cmddatalong[3] = jtagarm7tdmi_instr_primitive(instr, 0);
520   cmddatalong[4] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
521   cmddatalong[5] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
522   // inject long
523   cmddatalong[6] = jtagarm7tdmi_instr_primitive(parameter, 0);
524   cmddatalong[7] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
525   retval = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
526   cmddatalong[9] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
527   cmddatalong[8] = retval;
528
529   return(retval);
530 }
531
532 //! Retrieve a 32-bit Register value
533 unsigned long jtagarm7tdmi_get_register(unsigned char reg) {
534   unsigned long retval = 0, instr;
535   //JTAGARM7TDMI_RESETTAP();
536   // select chain 1, automatically put in INTEST
537   jtagarm7tdmi_scan_intest(1);
538   instr = ARM_INSTR_STR_Rx_r14 + ((reg<<12)&0xf00);
539   //retval = jtagarm7tdmi_exec(instr, 0);
540   // push STR_Rx, [R14] into pipeline
541   cmddatalong[1] = jtagarm7tdmi_instr_primitive(ARM_INSTR_LDR_R1_r0_4, 0);
542   // push nop into pipeline - fetched
543   cmddatalong[2] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
544   // push nop into pipeline - decoded
545   cmddatalong[3] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
546   // push nop into pipeline - executed 
547   cmddatalong[4] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
548   // recover 32-bit word
549   //retval = jtagarmtransn(0, 32, LSB, END, RETIDLE);
550   retval = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
551   cmddatalong[5] = retval;
552   cmddatalong[6] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
553   cmddatalong[7] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
554   cmddatalong[8] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
555   return retval;
556 }
557
558 //! Set a 32-bit Register value
559 unsigned long jtagarm7tdmi_set_register(unsigned char reg, unsigned long val) {
560   unsigned long retval = 0, instr;
561   //jtagarm7tdmi_resettap();
562   // select chain 1
563   jtagarm7tdmi_scan_intest(1);
564   instr = ARM_INSTR_LDR_Rx_r14 + ((reg<<12)&0xf00);
565   //retval = jtagarm7tdmi_exec(instr, 0);
566   // push STR_Rx, [R14] into pipeline
567   cmddatalong[1] = jtagarm7tdmi_instr_primitive(instr, 0);
568   // push nop into pipeline - fetched
569   cmddatalong[2] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
570   // push nop into pipeline - decoded
571   cmddatalong[2] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
572   
573   // push 32-bit word on data bus - execute state
574   //retval = jtagarmtransn(val, 32, LSB, END, RETIDLE);
575   cmddatalong[3] = jtagarm7tdmi_instr_primitive(val, 0);
576   // push nop into pipeline - executed 
577   cmddatalong[4] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
578   if (reg == ARM_REG_PC){
579     cmddatalong[5] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
580     cmddatalong[6] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
581   }
582   retval = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
583   cmddatalong[7] = retval;
584   return(retval);
585 }
586
587
588
589 //! Get all registers.  Return an array
590 unsigned long* jtagarm7tdmi_get_registers() {
591   jtagarm7tdmi_scan_intest(1);
592   cmddatalong[1] = jtagarm7tdmi_instr_primitive(ARM_INSTR_SKANKREGS,0);
593   cmddatalong[2] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
594   cmddatalong[3] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
595   cmddatalong[4] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
596   cmddatalong[5] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
597   cmddatalong[6] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
598   cmddatalong[7] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
599   cmddatalong[8] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
600   cmddatalong[9] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
601   cmddatalong[10] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
602   cmddatalong[11] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
603   cmddatalong[12] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
604   cmddatalong[13] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
605   cmddatalong[14] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
606   cmddatalong[15] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
607   cmddatalong[16] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
608   cmddatalong[17] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
609   cmddatalong[18] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
610   cmddatalong[19] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
611   cmddatalong[20] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
612   return registers;
613 }
614
615 //! Retrieve the CPSR Register value
616 unsigned long jtagarm7tdmi_get_regCPSR() {
617   unsigned long retval = 0;
618   // select chain 1
619   cmddatalong[1] = jtagarm7tdmi_scan_intest(1);
620
621   // push STR_Rx, [R14] into pipeline
622   cmddatalong[2] = jtagarm7tdmi_instr_primitive(ARM_INSTR_MRS_R0_CPSR, 0);
623   // push nop into pipeline - fetched
624   cmddatalong[3] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
625   // push nop into pipeline - decoded
626   cmddatalong[4] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
627   // push nop into pipeline - executed 
628   cmddatalong[5] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
629   // recover 32-bit word
630   retval = jtagarmtransn(0, 32, LSB, END, RETIDLE);
631   cmddatalong[6] = retval;
632   return retval;
633 }
634
635 //! Retrieve the CPSR Register value
636 unsigned long jtagarm7tdmi_set_regCPSR(unsigned long val) {
637   unsigned long retval = 0;
638   // select chain 1
639   jtagarm7tdmi_scan_intest(1);
640
641   // push MSR cpsr_cxsf, R0 into pipeline
642   cmddatalong[1] = jtagarm7tdmi_instr_primitive(ARM_INSTR_MSR_cpsr_cxsf_R0, 0);
643   // push nop into pipeline - fetched
644   cmddatalong[2] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
645   // push nop into pipeline - decoded
646   cmddatalong[3] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
647   
648   // push 32-bit word on data bus
649   retval = jtagarmtransn(val, 32, LSB, END, RETIDLE);
650   // push nop into pipeline - executed 
651   cmddatalong[5] = jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
652   cmddatalong[4] = retval;
653   return(retval);
654 }
655
656 //! Write data to address - Assume TAP in run-test/idle state
657 unsigned long jtagarm7tdmi_writemem(unsigned long adr, unsigned long data){
658   unsigned long r0=0, r1=-1;
659   // select chain 1
660   jtagarm7tdmi_scan_intest(1);
661
662   // store R0 and R1
663   r0 = jtagarm7tdmi_get_register(0);
664   r1 = jtagarm7tdmi_get_register(1);
665   // write address into R0
666   jtagarm7tdmi_set_register(0, adr);
667   // write data in R1
668   jtagarm7tdmi_set_register(1, data);
669   //retval = jtagarm7tdmi_exec(ARM_INSTR_LDR_R1_r0_4,1);
670   // push nop into pipeline to "clean" it ???
671   jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
672   // push nop into pipeline with BREAKPT set
673   jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 1);
674   // push LDR R1, R0, #4 into instruction pipeline
675   jtagarm7tdmi_instr_primitive(ARM_INSTR_LDR_R1_r0_4, 0);
676   // push nop into pipeline
677   jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
678   // restore R0 and R1 
679   jtagarm7tdmi_set_register(1, r1);
680   jtagarm7tdmi_set_register(0, r0);
681   return(-1);
682 }
683
684 //! Read data from address
685 unsigned long jtagarm7tdmi_readmem(unsigned long adr){
686   unsigned long retval = 0;
687   unsigned long r0=0, r1=-1;
688   int waitcount = 0xfff;
689   // select chain 1
690   jtagarm7tdmi_scan_intest(1);
691
692   // select chain 2
693   // store R0 and R1  - not yet...
694   r0 = jtagarm7tdmi_get_register(0);
695   r1 = jtagarm7tdmi_get_register(1);
696   // write address into R0
697   jtagarm7tdmi_set_register(0, adr);
698   // push nop into pipeline to "clean" it ???
699   jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
700   // push nop into pipeline with BREAKPT set
701   jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 1);
702   // push LDR R1, R0, #4 into instruction pipeline
703   jtagarm7tdmi_instr_primitive(ARM_INSTR_LDR_R1_r0_4, 0);
704   // push nop into pipeline
705   jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, 0);
706   // SHIFT_IR with RESTART instruction
707   jtagarm7tdmi_restart();
708   // Poll the Debug Status Register for DBGACK and nMREQ to be HIGH
709   while ((jtagarm7tdmi_get_dbgstate() & 1) == 0  && waitcount > 0){
710     delay(1);
711     waitcount --;
712   }
713   if (waitcount == 0xffff){
714     return (-1);
715   } else {
716     retval = jtagarm7tdmi_get_register(1);
717   // read memory value from R1 register
718   // restore R0 and R1 
719   jtagarm7tdmi_set_register(1, r1);
720   jtagarm7tdmi_set_register(0, r0);
721   }
722   return retval;
723 }
724
725
726 //! Read Program Counter
727 unsigned long jtagarm7tdmi_getpc(){
728   return jtagarm7tdmi_get_register(ARM_REG_PC);
729 }
730
731 //! Set Program Counter
732 unsigned long jtagarm7tdmi_setpc(unsigned long adr){
733   return jtagarm7tdmi_set_register(ARM_REG_PC, adr);
734 }
735
736 //! Halt CPU - returns 0xffff if the operation fails to complete within 
737 unsigned long jtagarm7tdmi_haltcpu(){                   //  PROVEN
738   int waitcount = 0xfff;
739   // select ICEBreaker
740   jtagarm7tdmi_scan_intest(2);
741   // store watchpoint info?  - not right now
742   // write 0 in watchpoint 1 address
743   eice_write(EICE_WP1ADDR, 0);
744   // write 0xffffffff in watchpoint 1 address mask
745   eice_write(EICE_WP1ADDRMASK, 0xffffffff);
746   // write 0 in watchpoint 1 data
747   eice_write(EICE_WP1DATA, 0);
748   // write 0xffffffff in watchpoint 1 data mask
749   eice_write(EICE_WP1DATAMASK, 0xffffffff);
750   // write 0x00000100 in watchpoint 1 control value register (enables watchpoint)
751   eice_write(EICE_WP1CTRL, 0x100);                              //!!!!! WTF!  THIS IS SUPPOSED TO BE 9 bits wide?!?
752   // write 0xfffffff7 in watchpoint 1 control mask - only detect the fetch instruction
753   eice_write(EICE_WP1CTRLMASK, 0xfffffff7);                     //!!!!! WTF!  THIS IS SUPPOSED TO BE 8 bits wide?!?
754   // poll until debug status says the cpu is in debug mode
755   while (!(jtagarm7tdmi_get_dbgstate() & 0x1)   && waitcount > 0){
756     delay(5);
757     waitcount --;
758   }
759   // write 0 in watchpoint 0 control value - disables watchpoint 0
760   eice_write(EICE_WP1CTRL, 0x0);
761
762   // store the debug state
763   last_halt_debug_state = jtagarm7tdmi_get_dbgstate();
764   last_halt_pc = jtagarm7tdmi_getpc() - 4;   // assume -4 for entering debug mode via watchpoint.
765   count_dbgspd_instr_since_debug = 0;
766   count_sysspd_instr_since_debug = 0;
767   if (last_halt_debug_state & JTAG_ARM7TDMI_DBG_TBIT){
768     jtagarm7tdmi_setMode_ARM();
769   }
770   return waitcount;
771 }
772
773 unsigned long jtagarm7tdmi_releasecpu(){
774   int waitcount = 0xfff;
775   unsigned long instr;
776   // somehow determine what PC should be (a couple ways possible, calculations required)
777   jtagarm7tdmi_scan_intest(1);
778   // NOP
779   jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP,0);
780   // NOP/BREAKPT
781   jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP,1);
782
783   if (last_halt_debug_state & JTAG_ARM7TDMI_DBG_TBIT){      // FIXME:  FORKED.
784     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?
785     jtagarm7tdmi_instr_primitive(instr,0);
786   } else {
787     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?
788     jtagarm7tdmi_instr_primitive(instr,0);
789   }
790   // VERB_RESTART
791   SHIFT_IR;
792   jtagarmtransn(ARM7TDMI_IR_RESTART,4,LSB,END,RETIDLE);
793
794   // wait until restart-bit set in debug state register
795   while ((jtagarm7tdmi_get_dbgstate() & JTAG_ARM7TDMI_DBG_DBGACK) && waitcount > 0){
796     //delay(1);
797     waitcount --;
798   }
799   last_halt_debug_state = -1;
800   last_halt_pc = -1;
801   return 0;
802 }
803  
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818 //! Handles ARM7TDMI JTAG commands.  Forwards others to JTAG.
819 void jtagarm7tdmihandle(unsigned char app, unsigned char verb, unsigned long len){
820   register char blocks;
821   
822   unsigned int i,val;
823   unsigned long at;
824   
825   //jtagarm7tdmi_resettap();
826  
827   switch(verb){
828   case START:
829     //Enter JTAG mode.
830     cmddatalong[0] = jtagarm7tdmi_start();
831     cmddatalong[1] = jtagarm7tdmi_haltcpu();
832     //jtagarm7tdmi_resettap();
833     txdata(app,verb,0x8);
834     break;
835   case JTAGARM7TDMI_READMEM:
836   case PEEK:
837     blocks=(len>4?cmddata[4]:1);
838     at=cmddatalong[0];
839     
840     len=0x80;
841     txhead(app,verb,len);
842     
843     while(blocks--){
844       for(i=0;i<len;i+=2){
845         jtagarm7tdmi_resettap();
846         delay(10);
847         
848         val=jtagarm7tdmi_readmem(at);
849                 
850         at+=2;
851         serial_tx(val&0xFF);
852         serial_tx((val&0xFF00)>>8);
853       }
854     }
855     
856     break;
857   case JTAGARM7TDMI_GET_CHIP_ID:
858         jtagarm7tdmi_resettap();
859     cmddatalong[0] = jtagarm7tdmi_idcode();
860     txdata(app,verb,4);
861     break;
862
863
864   case JTAGARM7TDMI_WRITEMEM:
865   case POKE:
866         jtagarm7tdmi_resettap();
867     jtagarm7tdmi_writemem(cmddatalong[0],
868                        cmddataword[2]);
869     cmddataword[0]=jtagarm7tdmi_readmem(cmddatalong[0]);
870     txdata(app,verb,2);
871     break;
872
873   case JTAGARM7TDMI_HALTCPU:  
874     cmddatalong[0] = jtagarm7tdmi_haltcpu();
875     txdata(app,verb,4);
876     break;
877   case JTAGARM7TDMI_RELEASECPU:
878         jtagarm7tdmi_resettap();
879     cmddatalong[0] = jtagarm7tdmi_releasecpu();
880     txdata(app,verb,4);
881     break;
882   //unimplemented functions
883   //case JTAGARM7TDMI_SETINSTRFETCH:
884   //case JTAGARM7TDMI_WRITEFLASH:
885   //case JTAGARM7TDMI_ERASEFLASH:
886   case JTAGARM7TDMI_SET_PC:
887         jtagarm7tdmi_resettap();
888     cmddatalong[0] = jtagarm7tdmi_setpc(cmddatalong[0]);
889     txdata(app,verb,4);
890     break;
891   case JTAGARM7TDMI_GET_DEBUG_CTRL:
892         jtagarm7tdmi_resettap();
893     cmddatalong[0] = jtagarm7tdmi_get_dbgctrl();
894     txdata(app,verb,1);
895     break;
896   case JTAGARM7TDMI_SET_DEBUG_CTRL:
897         jtagarm7tdmi_resettap();
898     cmddatalong[0] = jtagarm7tdmi_set_dbgctrl(cmddata[0]);
899     txdata(app,verb,4);
900     break;
901   case JTAGARM7TDMI_GET_PC:
902         jtagarm7tdmi_resettap();
903     cmddatalong[0] = jtagarm7tdmi_getpc();
904     txdata(app,verb,4);
905     break;
906   case JTAGARM7TDMI_GET_DEBUG_STATE:
907     jtagarm7tdmi_resettap();            // Shouldn't need this, but currently do.  FIXME!
908     cmddatalong[0] = jtagarm7tdmi_get_dbgstate();
909     txdata(app,verb,4);
910     break;
911   //case JTAGARM7TDMI_GET_WATCHPOINT:
912   //case JTAGARM7TDMI_SET_WATCHPOINT:
913   case JTAGARM7TDMI_GET_REGISTER:
914         jtagarm7tdmi_resettap();
915     cmddatalong[0] = jtagarm7tdmi_get_register(cmddata[0]);
916     txdata(app,verb,96);
917     break;
918   case JTAGARM7TDMI_SET_REGISTER:
919         jtagarm7tdmi_resettap();
920     cmddatalong[0] = cmddatalong[1];
921     jtagarm7tdmi_set_register(cmddata[0], cmddatalong[1]);
922     txdata(app,verb,96);
923     break;
924   case JTAGARM7TDMI_GET_REGISTERS:
925         jtagarm7tdmi_resettap();
926     jtagarm7tdmi_get_registers();
927     txdata(app,verb,80);
928     break;
929   //case JTAGARM7TDMI_SET_REGISTERS:
930   case JTAGARM7TDMI_DEBUG_INSTR:
931         jtagarm7tdmi_resettap();
932     cmddataword[0] = jtagarm7tdmi_exec(cmddataword[0], cmddataword[1], cmddata[9]);
933     txdata(app,verb,80);
934     break;
935   case JTAGARM7TDMI_STEP_INSTR:
936 /*  case JTAGARM7TDMI_READ_CODE_MEMORY:
937   case JTAGARM7TDMI_WRITE_FLASH_PAGE:
938   case JTAGARM7TDMI_READ_FLASH_PAGE:
939   case JTAGARM7TDMI_MASS_ERASE_FLASH:
940   case JTAGARM7TDMI_PROGRAM_FLASH:
941   case JTAGARM7TDMI_LOCKCHIP:
942   case JTAGARM7TDMI_CHIP_ERASE:
943   */
944 // Really ARM specific stuff
945   case JTAGARM7TDMI_GET_CPSR:
946         jtagarm7tdmi_resettap();
947     cmddatalong[0] = jtagarm7tdmi_get_regCPSR();
948     txdata(app,verb,4);
949     break;
950   case JTAGARM7TDMI_SET_CPSR:
951         jtagarm7tdmi_resettap();
952     cmddatalong[0] = jtagarm7tdmi_set_regCPSR(cmddatalong[0]);
953     txdata(app,verb,4);
954     break;
955   case JTAGARM7TDMI_GET_SPSR:           // FIXME: NOT CORRECT
956         jtagarm7tdmi_resettap();
957     cmddatalong[0] = jtagarm7tdmi_get_regCPSR();
958     txdata(app,verb,4);
959     break;
960   case JTAGARM7TDMI_SET_SPSR:           // FIXME: NOT CORRECT
961         jtagarm7tdmi_resettap();
962     cmddatalong[0] = jtagarm7tdmi_set_regCPSR(cmddatalong[0]);
963     txdata(app,verb,4);
964     break;
965   case JTAGARM7TDMI_SET_MODE_THUMB:
966   case JTAGARM7TDMI_SET_MODE_ARM:
967         jtagarm7tdmi_resettap();
968     cmddataword[0] = jtagarm7tdmi_setMode_ARM();
969     txdata(app,verb,4);
970     break;
971     
972   case 0xD0:          // loopback test
973     jtagarm7tdmi_resettap();
974     cmddatalong[0] = jtagarm7tdmi_bypass(cmddatalong[0]);
975     txdata(app,verb,4);
976     break;
977   case 0xD1:          // Set Scan Chain
978     jtagarm7tdmi_resettap();
979     cmddatalong[1] = jtagarm7tdmi_scan_intest(cmddataword[0]);
980     SHIFT_DR;
981     cmddatalong[0] = jtagarmtransn(cmddataword[2], 32, LSB, END, RETIDLE);
982     
983     txdata(app,verb,8);
984     break;
985   case 0xD2:          // DBGSTATE
986     cmddatalong[0] = jtagarm7tdmi_get_dbgstate();
987     txdata(app,verb,4);
988     break;
989   case 0xD3:          // EXECUTE
990     jtagarm7tdmi_resettap();
991     //cmddatalong[0] = jtagarm7tdmi_exec(cmddatalong[0], EXECNOPARM, 0);
992     cmddatalong[0] = test_exec(cmddatalong[0], EXECNOPARM, 0);
993     txdata(app,verb,52);
994     break;
995   case 0xD4:          // GET REGISTER
996     jtagarm7tdmi_resettap();
997     cmddatalong[0] = jtagarm7tdmi_get_register(cmddata[0]);
998     txdata(app,verb,40);
999     break;
1000   case 0xD5:          // SET REGISTER
1001     jtagarm7tdmi_resettap();
1002     cmddatalong[0] = jtagarm7tdmi_set_register(cmddata[0], cmddatalong[1]);
1003     txdata(app,verb,40);
1004     break;
1005   case 0xD6:          // SHIFT_DR
1006     SHIFT_DR;
1007     cmddatalong[0] = jtagarmtransn(cmddatalong[0], 32, LSB, END, RETIDLE);
1008     txdata(app,verb,4);
1009     break;
1010   case 0xD7:          // INSTR_PRIMITIVE
1011     jtagarm7tdmi_resettap();
1012     // select chain 1
1013     jtagarm7tdmi_scan_intest(1);
1014     cmddatalong[0] = jtagarm7tdmi_instr_primitive(cmddatalong[0], 0);
1015     txdata(app,verb,4);
1016     break;
1017   case 0xD8:          // EICE_READ
1018     jtagarm7tdmi_resettap();
1019     cmddatalong[0] = eice_read(cmddatalong[0]);
1020     txdata(app,verb,4);
1021     break;
1022   case 0xD9:          // EICE_WRITE
1023     jtagarm7tdmi_resettap();
1024     cmddatalong[0] = eice_write(cmddatalong[0], cmddatalong[1]);
1025     txdata(app,verb,4);
1026     break;
1027   case 0xDA:          // TEST MSB THROUGH CHAIN0 and CHAIN1
1028     jtagarm7tdmi_resettap();
1029     jtagarm7tdmi_scan_intest(0);
1030     cmddatalong[0] = jtagarmtransn(0x41414141, 32, MSB, NOEND, NORETIDLE);
1031     cmddatalong[1] = jtagarmtransn(0x42424242, 32, MSB, NOEND, NORETIDLE);
1032     cmddatalong[2] = jtagarmtransn(0x43434343,  9, MSB, NOEND, NORETIDLE);
1033     cmddatalong[3] = jtagarmtransn(0x44444444, 32, MSB, NOEND, NORETIDLE);
1034     cmddatalong[4] = jtagarmtransn(cmddatalong[0], 32, MSB, NOEND, NORETIDLE);
1035     cmddatalong[5] = jtagarmtransn(cmddatalong[1], 32, MSB, NOEND, NORETIDLE);
1036     cmddatalong[6] = jtagarmtransn(cmddatalong[2],  9, MSB, NOEND, NORETIDLE);
1037     cmddatalong[7] = jtagarmtransn(cmddatalong[3], 32, MSB, END, RETIDLE);
1038     jtagarm7tdmi_resettap();
1039     jtagarm7tdmi_scan_intest(1);
1040     cmddatalong[8] = jtagarmtransn(0x41414141, 32, MSB, NOEND, NORETIDLE);
1041     cmddatalong[9] = jtagarmtransn(0x44444444,  1, MSB, NOEND, NORETIDLE);
1042     cmddatalong[10] = jtagarmtransn(cmddatalong[8], 32, MSB, NOEND, NORETIDLE);
1043     cmddatalong[11] = jtagarmtransn(cmddatalong[9],  1, MSB, END, RETIDLE);
1044     txdata(app,verb,48);
1045     break;
1046   case 0xDB:          // WHATEVER IR, READ 32
1047     jtagarm7tdmi_resettap();
1048     SHIFT_IR;
1049     jtagarmtransn(cmddata[0], 4, LSB, END, NORETIDLE);
1050     SHIFT_DR;
1051     cmddatalong[0] = jtagarmtransn(cmddatalong[1], 32, LSB, END, RETIDLE);
1052     txdata(app,verb,8);
1053     break;
1054     
1055   default:
1056     jtaghandle(app,verb,len);
1057   }
1058 }