- convert all files to unix line-ending
[fw/openocd] / src / target / arm11_dbgtap.c
1 /***************************************************************************
2  *   Copyright (C) 2008 digenius technology GmbH.                          *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
18  ***************************************************************************/
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "arm11.h"
25 #include "jtag.h"
26 #include "log.h"
27
28 #include <stdlib.h>
29 #include <string.h>
30
31 #if 0
32 #define JTAG_DEBUG(expr ...) \
33         do { \
34             log_printf (LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, expr); \
35         } while(0)
36 #else
37 #define JTAG_DEBUG(expr ...) \
38         do {} while(0)
39 #endif
40
41 /** Code de-clutter: Construct scan_field_t to write out a value
42  *
43  * \param arm11         Target state variable.
44  * \param num_bits      Length of the data field
45  * \param out_data      pointer to the data that will be sent out
46  *                      <em>(data is read when it is added to the JTAG queue)</em>
47  * \param in_data       pointer to the memory that will receive data that was clocked in
48  *                      <em>(data is written when the JTAG queue is executed)</em>
49  * \param field target data structure that will be initialized
50  */
51 void arm11_setup_field(arm11_common_t * arm11, int num_bits, void * out_data, void * in_data, scan_field_t * field)
52 {
53     field->device               = arm11->jtag_info.chain_pos;
54     field->num_bits             = num_bits;
55     field->out_mask             = NULL;
56     field->in_check_mask        = NULL;
57     field->in_check_value       = NULL;
58     field->in_handler           = NULL;
59     field->in_handler_priv      = NULL;
60
61     field->out_value            = out_data;
62     field->in_value             = in_data;
63 }
64
65
66 /** Write JTAG instruction register
67  *
68  * \param arm11 Target state variable.
69  * \param instr An ARM11 DBGTAP instruction. Use enum #arm11_instructions.
70  * \param state Pass the final TAP state or -1 for the default value (Pause-IR).
71  *
72  * \remarks This adds to the JTAG command queue but does \em not execute it.
73  */
74 void arm11_add_IR(arm11_common_t * arm11, u8 instr, enum tap_state state)
75 {
76     jtag_device_t *device = jtag_get_device(arm11->jtag_info.chain_pos);
77
78     if (buf_get_u32(device->cur_instr, 0, 5) == instr)
79     {
80         JTAG_DEBUG("IR <= 0x%02x SKIPPED", instr);
81         return;
82     }
83
84     JTAG_DEBUG("IR <= 0x%02x", instr);
85
86     scan_field_t field;
87
88     arm11_setup_field(arm11, 5, &instr, NULL, &field);
89
90     jtag_add_ir_scan_vc(1, &field, state == -1 ? TAP_PI : state);
91 }
92
93 /** Verify shifted out data from Scan Chain Register (SCREG)
94  *  Used as parameter to scan_field_t::in_handler in
95  *  arm11_add_debug_SCAN_N().
96  *
97  */
98 static int arm11_in_handler_SCAN_N(u8 *in_value, void *priv, struct scan_field_s *field)
99 {
100     /** \todo TODO: clarify why this isnt properly masked in jtag.c jtag_read_buffer() */
101     u8 v = *in_value & 0x1F;
102
103     if (v != 0x10)
104     {
105         ERROR("'arm11 target' JTAG communication error SCREG SCAN OUT 0x%02x (expected 0x10)", v);
106         exit(-1);
107     }
108
109     JTAG_DEBUG("SCREG SCAN OUT 0x%02x", v);
110     return ERROR_OK;
111 }
112
113 /** Select and write to Scan Chain Register (SCREG)
114  * 
115  * This function sets the instruction register to SCAN_N and writes
116  * the data register with the selected chain number.
117  *
118  * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301f/Cacbjhfg.html
119  *
120  * \param arm11     Target state variable.
121  * \param chain     Scan chain that will be selected.
122  * \param state     Pass the final TAP state or -1 for the default
123  *                  value (Pause-DR).
124  *
125  * The chain takes effect when Update-DR is passed (usually when subsequently
126  * the INTEXT/EXTEST instructions are written).
127  *
128  * \warning (Obsolete) Using this twice in a row will \em fail. The first call will end
129  *          in Pause-DR. The second call, due to the IR caching, will not
130  *          go through Capture-DR when shifting in the new scan chain number.
131  *          As a result the verification in arm11_in_handler_SCAN_N() must
132  *          fail.
133  *
134  * \remarks This adds to the JTAG command queue but does \em not execute it.
135  */
136
137 void arm11_add_debug_SCAN_N(arm11_common_t * arm11, u8 chain, enum tap_state state)
138 {
139     JTAG_DEBUG("SCREG <= 0x%02x", chain);
140
141     arm11_add_IR(arm11, ARM11_SCAN_N, -1);
142
143     scan_field_t                field;
144
145     arm11_setup_field(arm11, 5, &chain, NULL, &field);
146
147     field.in_handler = arm11_in_handler_SCAN_N;
148
149     jtag_add_dr_scan_vc(1, &field, state == -1 ? TAP_PD : state);
150 }
151
152 /** Write an instruction into the ITR register
153  * 
154  * \param arm11 Target state variable.
155  * \param inst  An ARM11 processor instruction/opcode.
156  * \param flag  Optional parameter to retrieve the InstCompl flag
157  *              (this will be written when the JTAG chain is executed). 
158  * \param state Pass the final TAP state or -1 for the default
159  *              value (Run-Test/Idle).
160  *
161  * \remarks By default this ends with Run-Test/Idle state
162  * and causes the instruction to be executed. If
163  * a subsequent write to DTR is needed before
164  * executing the instruction then TAP_PD should be
165  * passed to \p state.
166  *
167  * \remarks This adds to the JTAG command queue but does \em not execute it.
168  */
169 void arm11_add_debug_INST(arm11_common_t * arm11, u32 inst, u8 * flag, enum tap_state state)
170 {
171     JTAG_DEBUG("INST <= 0x%08x", inst);
172
173     scan_field_t                itr[2];
174
175     arm11_setup_field(arm11, 32,    &inst,      NULL, itr + 0);
176     arm11_setup_field(arm11, 1,     NULL,       flag, itr + 1);
177
178     jtag_add_dr_scan_vc(asizeof(itr), itr, state == -1 ? TAP_RTI : state);
179 }
180
181 /** Read the Debug Status and Control Register (DSCR)
182  *
183  * same as CP14 c1
184  *
185  * \param arm11 Target state variable.
186  * \return DSCR content
187  * 
188  * \remarks This is a stand-alone function that executes the JTAG command queue.
189  */
190 u32 arm11_read_DSCR(arm11_common_t * arm11)
191 {
192     arm11_add_debug_SCAN_N(arm11, 0x01, -1);
193
194     arm11_add_IR(arm11, ARM11_INTEST, -1);
195
196     u32                 dscr;
197     scan_field_t        chain1_field;
198
199     arm11_setup_field(arm11, 32, NULL, &dscr, &chain1_field);
200
201     jtag_add_dr_scan_vc(1, &chain1_field, TAP_PD);
202
203     jtag_execute_queue();
204
205     if (arm11->last_dscr != dscr)
206         JTAG_DEBUG("DSCR  = %08x (OLD %08x)", dscr, arm11->last_dscr);
207
208     arm11->last_dscr = dscr;
209
210     return dscr;
211 }
212
213 /** Write the Debug Status and Control Register (DSCR)
214  *
215  * same as CP14 c1
216  *
217  * \param arm11 Target state variable.
218  * \param dscr DSCR content
219  * 
220  * \remarks This is a stand-alone function that executes the JTAG command queue.
221  */
222 void arm11_write_DSCR(arm11_common_t * arm11, u32 dscr)
223 {
224     arm11_add_debug_SCAN_N(arm11, 0x01, -1);
225
226     arm11_add_IR(arm11, ARM11_EXTEST, -1);
227
228     scan_field_t                    chain1_field;
229
230     arm11_setup_field(arm11, 32, &dscr, NULL, &chain1_field);
231
232     jtag_add_dr_scan_vc(1, &chain1_field, TAP_PD);
233
234     jtag_execute_queue();
235
236     JTAG_DEBUG("DSCR <= %08x (OLD %08x)", dscr, arm11->last_dscr);
237
238     arm11->last_dscr = dscr;
239 }
240
241
242
243 /** Get the debug reason from Debug Status and Control Register (DSCR)
244  *
245  * \param dscr DSCR value to analyze
246  * \return Debug reason
247  * 
248  */
249 enum target_debug_reason arm11_get_DSCR_debug_reason(u32 dscr)
250 {
251     switch (dscr & ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_MASK)
252     {
253     case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_HALT:                 return DBG_REASON_DBGRQ;
254     case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BREAKPOINT:           return DBG_REASON_BREAKPOINT;
255     case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_WATCHPOINT:           return DBG_REASON_WATCHPOINT;
256     case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_BKPT_INSTRUCTION:     return DBG_REASON_BREAKPOINT;
257     case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_EDBGRQ:               return DBG_REASON_DBGRQ;
258     case ARM11_DSCR_METHOD_OF_DEBUG_ENTRY_VECTOR_CATCH:         return DBG_REASON_BREAKPOINT;
259
260     default:
261         return DBG_REASON_DBGRQ;
262     }
263 };
264
265
266
267 /** Prepare the stage for ITR/DTR operations
268  * from the arm11_run_instr... group of functions.
269  *
270  * Put arm11_run_instr_data_prepare() and arm11_run_instr_data_finish()
271  * around a block of arm11_run_instr_... calls.
272  *
273  * Select scan chain 5 to allow quick access to DTR. When scan
274  * chain 4 is needed to put in a register the ITRSel instruction
275  * shortcut is used instead of actually changing the Scan_N
276  * register.
277  *
278  * \param arm11 Target state variable.
279  *
280  */
281 void arm11_run_instr_data_prepare(arm11_common_t * arm11)
282 {
283     arm11_add_debug_SCAN_N(arm11, 0x05, -1);
284 }
285
286 /** Cleanup after ITR/DTR operations
287  * from the arm11_run_instr... group of functions
288  *
289  * Put arm11_run_instr_data_prepare() and arm11_run_instr_data_finish()
290  * around a block of arm11_run_instr_... calls.
291  *
292  * Any RTI can lead to an instruction execution when
293  * scan chains 4 or 5 are selected and the IR holds
294  * INTEST or EXTEST. So we must disable that before
295  * any following activities lead to an RTI.
296  *
297  * \param arm11 Target state variable.
298  *
299  */
300 void arm11_run_instr_data_finish(arm11_common_t * arm11)
301 {
302     arm11_add_debug_SCAN_N(arm11, 0x00, -1);
303 }
304
305
306 /** Execute one or multiple instructions via ITR
307  *
308  * \pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block
309  *
310  * \param arm11         Target state variable.
311  * \param opcode        Pointer to sequence of ARM opcodes
312  * \param count         Number of opcodes to execute
313  *
314  */
315 void arm11_run_instr_no_data(arm11_common_t * arm11, u32 * opcode, size_t count)
316 {
317     arm11_add_IR(arm11, ARM11_ITRSEL, -1);
318
319     while (count--)
320     {
321         arm11_add_debug_INST(arm11, *opcode++, NULL, TAP_RTI);
322
323         while (1)
324         {
325             u8 flag;
326
327             arm11_add_debug_INST(arm11, 0, &flag, count ? TAP_RTI : TAP_PD);
328
329             jtag_execute_queue();
330
331             if (flag)
332                 break;
333         }
334     }
335 }
336
337 /** Execute one instruction via ITR
338  *
339  * \pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block
340  *
341  * \param arm11         Target state variable.
342  * \param opcode        ARM opcode
343  *
344  */
345 void arm11_run_instr_no_data1(arm11_common_t * arm11, u32 opcode)
346 {
347     arm11_run_instr_no_data(arm11, &opcode, 1);
348 }
349
350
351 /** Execute one instruction via ITR repeatedly while
352  *  passing data to the core via DTR on each execution.
353  *
354  *  The executed instruction \em must read data from DTR.
355  *
356  * \pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block
357  *
358  * \param arm11         Target state variable.
359  * \param opcode        ARM opcode
360  * \param data          Pointer to the data words to be passed to the core
361  * \param count         Number of data words and instruction repetitions
362  *
363  */
364 void arm11_run_instr_data_to_core(arm11_common_t * arm11, u32 opcode, u32 * data, size_t count)
365 {
366     arm11_add_IR(arm11, ARM11_ITRSEL, -1);
367
368     arm11_add_debug_INST(arm11, opcode, NULL, TAP_PD);
369
370     arm11_add_IR(arm11, ARM11_EXTEST, -1);
371
372     scan_field_t        chain5_fields[3];
373
374     u32                 Data;
375     u8                  Ready;
376     u8                  nRetry;
377
378     arm11_setup_field(arm11, 32,    &Data,  NULL,       chain5_fields + 0);
379     arm11_setup_field(arm11,  1,    NULL,   &Ready,     chain5_fields + 1);
380     arm11_setup_field(arm11,  1,    NULL,   &nRetry,    chain5_fields + 2);
381
382     while (count--)
383     {
384         do
385         {
386             Data            = *data;
387
388             jtag_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_RTI);
389             jtag_execute_queue();
390
391             JTAG_DEBUG("DTR  Ready %d  nRetry %d", Ready, nRetry);
392         }
393         while (!Ready);
394
395         data++;
396     }
397
398     arm11_add_IR(arm11, ARM11_INTEST, -1);
399
400     do
401     {
402         Data        = 0;
403
404         jtag_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_PD);
405         jtag_execute_queue();
406
407         JTAG_DEBUG("DTR  Data %08x  Ready %d  nRetry %d", Data, Ready, nRetry);
408     }
409     while (!Ready);
410
411
412 }
413
414 /** Execute an instruction via ITR while handing data into the core via DTR.
415  *
416  *  The executed instruction \em must read data from DTR.
417  *
418  * \pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block
419  *
420  * \param arm11         Target state variable.
421  * \param opcode        ARM opcode
422  * \param data          Data word to be passed to the core via DTR
423  *
424  */
425 void arm11_run_instr_data_to_core1(arm11_common_t * arm11, u32 opcode, u32 data)
426 {
427     arm11_run_instr_data_to_core(arm11, opcode, &data, 1);
428 }
429
430
431 /** Execute one instruction via ITR repeatedly while
432  *  reading data from the core via DTR on each execution.
433  *
434  *  The executed instruction \em must write data to DTR.
435  *
436  * \pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block
437  *
438  * \param arm11         Target state variable.
439  * \param opcode        ARM opcode
440  * \param data          Pointer to an array that receives the data words from the core
441  * \param count         Number of data words and instruction repetitions
442  *
443  */
444 void arm11_run_instr_data_from_core(arm11_common_t * arm11, u32 opcode, u32 * data, size_t count)
445 {
446     arm11_add_IR(arm11, ARM11_ITRSEL, -1);
447
448     arm11_add_debug_INST(arm11, opcode, NULL, TAP_RTI);
449
450     arm11_add_IR(arm11, ARM11_INTEST, -1);
451
452     scan_field_t        chain5_fields[3];
453
454     u32                 Data;
455     u8                  Ready;
456     u8                  nRetry;
457
458     arm11_setup_field(arm11, 32,    NULL,       &Data,      chain5_fields + 0);
459     arm11_setup_field(arm11,  1,    NULL,       &Ready,     chain5_fields + 1);
460     arm11_setup_field(arm11,  1,    NULL,       &nRetry,    chain5_fields + 2);
461
462     while (count--)
463     {
464         do
465         {
466             jtag_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, count ? TAP_RTI : TAP_PD);
467             jtag_execute_queue();
468
469             JTAG_DEBUG("DTR  Data %08x  Ready %d  nRetry %d", Data, Ready, nRetry);
470         }
471         while (!Ready);
472
473         *data++ = Data;
474     }
475 }
476
477 /** Execute one instruction via ITR
478  *  then load r0 into DTR and read DTR from core.
479  *
480  *  The first executed instruction (\p opcode) should write data to r0.
481  *
482  * \pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block
483  *
484  * \param arm11         Target state variable.
485  * \param opcode        ARM opcode to write r0 with the value of interest
486  * \param data          Pointer to a data word that receives the value from r0 after \p opcode was executed.
487  *
488  */
489 void arm11_run_instr_data_from_core_via_r0(arm11_common_t * arm11, u32 opcode, u32 * data)
490 {
491     arm11_run_instr_no_data1(arm11, opcode);
492
493     /* MCR p14,0,R0,c0,c5,0 (move r0 -> wDTR -> local var) */
494     arm11_run_instr_data_from_core(arm11, 0xEE000E15, data, 1);
495 }
496
497 /** Load data into core via DTR then move it to r0 then
498  *  execute one instruction via ITR
499  *
500  *  The final executed instruction (\p opcode) should read data from r0.
501  *
502  * \pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block
503  *
504  * \param arm11         Target state variable.
505  * \param opcode        ARM opcode to read r0 act upon it
506  * \param data          Data word that will be written to r0 before \p opcode is executed
507  *
508  */
509 void arm11_run_instr_data_to_core_via_r0(arm11_common_t * arm11, u32 opcode, u32 data)
510 {
511     /* MRC p14,0,r0,c0,c5,0 */
512     arm11_run_instr_data_to_core1(arm11, 0xEE100E15, data);
513
514     arm11_run_instr_no_data1(arm11, opcode);
515 }
516
517
518 void arm11_sc7_run(arm11_common_t * arm11, arm11_sc7_action_t * actions, size_t count)
519 {
520     arm11_add_debug_SCAN_N(arm11, 0x07, -1);
521
522     arm11_add_IR(arm11, ARM11_EXTEST, -1);
523
524     scan_field_t        chain7_fields[3];
525
526     u8          nRW;
527     u32         DataOut;
528     u8          AddressOut;
529     u8          Ready;
530     u32         DataIn;
531     u8          AddressIn;
532
533     arm11_setup_field(arm11,  1, &nRW,          &Ready,         chain7_fields + 0);
534     arm11_setup_field(arm11, 32, &DataOut,      &DataIn,        chain7_fields + 1);
535     arm11_setup_field(arm11,  7, &AddressOut,   &AddressIn,     chain7_fields + 2);
536
537     {size_t i;
538     for (i = 0; i < count + 1; i++)
539     {
540         if (i < count)
541         {
542             nRW         = actions[i].write ? 1 : 0;
543             DataOut     = actions[i].value;
544             AddressOut  = actions[i].address;
545         }
546         else
547         {
548             nRW         = 0;
549             DataOut     = 0;
550             AddressOut  = 0;
551         }
552
553         do
554         {
555             JTAG_DEBUG("SC7 <= Address %02x  Data %08x    nRW %d", AddressOut, DataOut, nRW);
556
557             jtag_add_dr_scan_vc(asizeof(chain7_fields), chain7_fields, TAP_PD);
558             jtag_execute_queue();
559
560             JTAG_DEBUG("SC7 => Address %02x  Data %08x  Ready %d", AddressIn, DataIn, Ready);
561         }
562         while (!Ready); /* 'nRW' is 'Ready' on read out */
563
564         if (i > 0)
565         {
566             if (actions[i - 1].address != AddressIn)
567             {
568                 WARNING("Scan chain 7 shifted out unexpected address");
569             }
570
571             if (!actions[i - 1].write)
572             {
573                 actions[i - 1].value = DataIn;
574             }
575             else
576             {
577                 if (actions[i - 1].value != DataIn)
578                 {
579                     WARNING("Scan chain 7 shifted out unexpected data");
580                 }
581             }
582         }
583     }}
584
585     {size_t i;
586     for (i = 0; i < count; i++)
587     {
588         JTAG_DEBUG("SC7 %02d: %02x %s %08x", i, actions[i].address, actions[i].write ? "<=" : "=>", actions[i].value);
589     }}
590 }
591
592 void arm11_sc7_clear_bw(arm11_common_t * arm11)
593 {
594     size_t actions = arm11->brp + arm11->wrp;
595
596     arm11_sc7_action_t          clear_bw[actions];
597
598     {size_t i;
599     for (i = 0; i < actions; i++)
600     {
601         clear_bw[i].write       = true;
602         clear_bw[i].value       = 0;
603         clear_bw[i].address     =
604             i < arm11->brp ?
605                 ARM11_SC7_BCR0 + i :
606                 ARM11_SC7_WCR0 + i - arm11->brp;
607     }}
608
609     arm11_sc7_run(arm11, clear_bw, actions);
610 }
611