2a32f1127b467ec9f4815f5a2f9ec486870dc491
[fw/openocd] / src / target / arm9tdmi.c
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   Copyright (C) 2008 by Spencer Oliver                                  *
6  *   spen@spen-soft.co.uk                                                  *
7  *                                                                         *
8  *   Copyright (C) 2008 by Hongtao Zheng                                   *
9  *   hontor@126.com                                                        *
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  *   This program is distributed in the hope that it will be useful,       *
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
19  *   GNU General Public License for more details.                          *
20  *                                                                         *
21  *   You should have received a copy of the GNU General Public License     *
22  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
23  ***************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "arm9tdmi.h"
30 #include "target_type.h"
31 #include "register.h"
32 #include "arm_opcodes.h"
33 #include "arm_semihosting.h"
34
35 /*
36  * NOTE:  this holds code that's used with multiple ARM9 processors:
37  *  - ARM9TDMI (ARMv4T) ... in ARM920, ARM922, and ARM940 cores
38  *  - ARM9E-S (ARMv5TE) ... in ARM946, ARM966, and ARM968 cores
39  *  - ARM9EJS (ARMv5TEJ) ... in ARM926 core
40  *
41  * In short, the file name is a misnomer ... it is NOT specific to
42  * that first generation ARM9 processor, or cores using it.
43  */
44
45 #if 0
46 #define _DEBUG_INSTRUCTION_EXECUTION_
47 #endif
48
49 enum arm9tdmi_vector_bit {
50         ARM9TDMI_RESET_VECTOR = 0x01,
51         ARM9TDMI_UNDEF_VECTOR = 0x02,
52         ARM9TDMI_SWI_VECTOR = 0x04,
53         ARM9TDMI_PABT_VECTOR = 0x08,
54         ARM9TDMI_DABT_VECTOR = 0x10,
55         /* BIT(5) reserved -- must be zero */
56         ARM9TDMI_IRQ_VECTOR = 0x40,
57         ARM9TDMI_FIQ_VECTOR = 0x80,
58 };
59
60 static const struct arm9tdmi_vector {
61         const char *name;
62         uint32_t value;
63 } arm9tdmi_vectors[] = {
64         {"reset", ARM9TDMI_RESET_VECTOR},
65         {"undef", ARM9TDMI_UNDEF_VECTOR},
66         {"swi", ARM9TDMI_SWI_VECTOR},
67         {"pabt", ARM9TDMI_PABT_VECTOR},
68         {"dabt", ARM9TDMI_DABT_VECTOR},
69         {"irq", ARM9TDMI_IRQ_VECTOR},
70         {"fiq", ARM9TDMI_FIQ_VECTOR},
71         {0, 0},
72 };
73
74 int arm9tdmi_examine_debug_reason(struct target *target)
75 {
76         int retval = ERROR_OK;
77         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
78
79         /* only check the debug reason if we don't know it already */
80         if ((target->debug_reason != DBG_REASON_DBGRQ)
81                         && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
82                 struct scan_field fields[3];
83                 uint8_t databus[4];
84                 uint8_t instructionbus[4];
85                 uint8_t debug_reason;
86
87                 fields[0].num_bits = 32;
88                 fields[0].out_value = NULL;
89                 fields[0].in_value = databus;
90
91                 fields[1].num_bits = 3;
92                 fields[1].out_value = NULL;
93                 fields[1].in_value = &debug_reason;
94
95                 fields[2].num_bits = 32;
96                 fields[2].out_value = NULL;
97                 fields[2].in_value = instructionbus;
98
99                 retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1, TAP_DRPAUSE);
100                 if (retval != ERROR_OK)
101                         return retval;
102                 retval = arm_jtag_set_instr(arm7_9->jtag_info.tap, arm7_9->jtag_info.intest_instr, NULL, TAP_DRPAUSE);
103                 if (retval != ERROR_OK)
104                         return retval;
105
106                 jtag_add_dr_scan(arm7_9->jtag_info.tap, 3, fields, TAP_DRPAUSE);
107                 retval = jtag_execute_queue();
108                 if (retval != ERROR_OK)
109                         return retval;
110
111                 fields[0].in_value = NULL;
112                 fields[0].out_value = databus;
113                 fields[1].in_value = NULL;
114                 fields[1].out_value = &debug_reason;
115                 fields[2].in_value = NULL;
116                 fields[2].out_value = instructionbus;
117
118                 jtag_add_dr_scan(arm7_9->jtag_info.tap, 3, fields, TAP_DRPAUSE);
119
120                 if (debug_reason & 0x4)
121                         if (debug_reason & 0x2)
122                                 target->debug_reason = DBG_REASON_WPTANDBKPT;
123                 else
124                         target->debug_reason = DBG_REASON_WATCHPOINT;
125                 else
126                         target->debug_reason = DBG_REASON_BREAKPOINT;
127         }
128
129         return ERROR_OK;
130 }
131
132 /* put an instruction in the ARM9TDMI pipeline or write the data bus,
133  * and optionally read data
134  */
135 int arm9tdmi_clock_out(struct arm_jtag *jtag_info, uint32_t instr,
136                 uint32_t out, uint32_t *in, int sysspeed)
137 {
138         int retval = ERROR_OK;
139         struct scan_field fields[3];
140         uint8_t out_buf[4];
141         uint8_t instr_buf[4];
142         uint8_t sysspeed_buf = 0x0;
143
144         /* prepare buffer */
145         buf_set_u32(out_buf, 0, 32, out);
146
147         buf_set_u32(instr_buf, 0, 32, flip_u32(instr, 32));
148
149         if (sysspeed)
150                 buf_set_u32(&sysspeed_buf, 2, 1, 1);
151
152         retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);
153         if (retval != ERROR_OK)
154                 return retval;
155
156         retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
157         if (retval != ERROR_OK)
158                 return retval;
159
160         fields[0].num_bits = 32;
161         fields[0].out_value = out_buf;
162         fields[0].in_value = NULL;
163
164         fields[1].num_bits = 3;
165         fields[1].out_value = &sysspeed_buf;
166         fields[1].in_value = NULL;
167
168         fields[2].num_bits = 32;
169         fields[2].out_value = instr_buf;
170         fields[2].in_value = NULL;
171
172         if (in) {
173                 fields[0].in_value = (uint8_t *)in;
174                 jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE);
175
176                 jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)in);
177         } else
178                 jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE);
179
180         jtag_add_runtest(0, TAP_DRPAUSE);
181
182 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
183         {
184                 retval = jtag_execute_queue();
185                 if (retval != ERROR_OK)
186                         return retval;
187
188                 if (in)
189                         LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr, out, *in);
190                 else
191                         LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr, out);
192         }
193 #endif
194
195         return ERROR_OK;
196 }
197
198 /* just read data (instruction and data-out = don't care) */
199 int arm9tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in)
200 {
201         int retval = ERROR_OK;
202         struct scan_field fields[3];
203
204         retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);
205         if (retval != ERROR_OK)
206                 return retval;
207
208         retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
209         if (retval != ERROR_OK)
210                 return retval;
211
212         fields[0].num_bits = 32;
213         fields[0].out_value = NULL;
214         fields[0].in_value = (uint8_t *)in;
215
216         fields[1].num_bits = 3;
217         fields[1].out_value = NULL;
218         fields[1].in_value = NULL;
219
220         fields[2].num_bits = 32;
221         fields[2].out_value = NULL;
222         fields[2].in_value = NULL;
223
224         jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE);
225
226         jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)in);
227
228         jtag_add_runtest(0, TAP_DRPAUSE);
229
230 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
231         {
232                 retval = jtag_execute_queue();
233                 if (retval != ERROR_OK)
234                         return retval;
235
236                 if (in)
237                         LOG_DEBUG("in: 0x%8.8x", *in);
238                 else
239                         LOG_ERROR("BUG: called with in == NULL");
240         }
241 #endif
242
243         return ERROR_OK;
244 }
245
246 /* clock the target, and read the databus
247  * the *in pointer points to a buffer where elements of 'size' bytes
248  * are stored in big (be == 1) or little (be == 0) endianness
249  */
250 int arm9tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info,
251                 void *in, int size, int be)
252 {
253         int retval = ERROR_OK;
254         struct scan_field fields[2];
255
256         retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);
257         if (retval != ERROR_OK)
258                 return retval;
259
260         retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
261         if (retval != ERROR_OK)
262                 return retval;
263
264         if (size == 4) {
265                 fields[0].num_bits = 32;
266                 fields[0].out_value = NULL;
267                 fields[0].in_value = in;
268
269                 fields[1].num_bits = 3 + 32;
270                 fields[1].out_value = NULL;
271                 fields[1].in_value = NULL;
272         } else {
273                 /* Discard irrelevant bits of the scan, making sure we don't write more
274                  * than size bytes to in */
275                 fields[0].num_bits = size * 8;
276                 fields[0].out_value = NULL;
277                 fields[0].in_value = in;
278
279                 fields[1].num_bits = 3 + 32 + 32 - size * 8;
280                 fields[1].out_value = NULL;
281                 fields[1].in_value = NULL;
282         }
283
284         jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE);
285
286         jtag_add_callback4(arm7_9_endianness_callback,
287                 (jtag_callback_data_t)in,
288                 (jtag_callback_data_t)size,
289                 (jtag_callback_data_t)be,
290                 (jtag_callback_data_t)0);
291
292         jtag_add_runtest(0, TAP_DRPAUSE);
293
294 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
295         {
296                 retval = jtag_execute_queue();
297                 if (retval != ERROR_OK)
298                         return retval;
299
300                 if (in)
301                         LOG_DEBUG("in: 0x%8.8x", *(uint32_t *)in);
302                 else
303                         LOG_ERROR("BUG: called with in == NULL");
304         }
305 #endif
306
307         return ERROR_OK;
308 }
309
310 static void arm9tdmi_change_to_arm(struct target *target,
311                 uint32_t *r0, uint32_t *pc)
312 {
313         int retval = ERROR_OK;
314         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
315         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
316
317         /* save r0 before using it and put system in ARM state
318          * to allow common handling of ARM and THUMB debugging */
319
320         /* fetch STR r0, [r0] */
321         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
322         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
323         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
324         /* STR r0, [r0] in Memory */
325         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, r0, 0);
326
327         /* MOV r0, r15 fetched, STR in Decode */
328         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), 0, NULL, 0);
329         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
330         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
331         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
332         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
333         /* nothing fetched, STR r0, [r0] in Memory */
334         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, pc, 0);
335
336         /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
337         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);
338         /* LDR in Decode */
339         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
340         /* LDR in Execute */
341         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
342         /* LDR in Memory (to account for interlock) */
343         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
344
345         /* fetch BX */
346         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), 0, NULL, 0);
347         /* NOP fetched, BX in Decode, MOV in Execute */
348         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
349         /* NOP fetched, BX in Execute (1) */
350         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
351
352         retval = jtag_execute_queue();
353         if (retval != ERROR_OK)
354                 return;
355
356         /* fix program counter:
357          * MOV r0, r15 was the 5th instruction (+8)
358          * reading PC in Thumb state gives address of instruction + 4
359          */
360         *pc -= 0xc;
361 }
362
363 void arm9tdmi_read_core_regs(struct target *target,
364                 uint32_t mask, uint32_t *core_regs[16])
365 {
366         int i;
367         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
368         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
369
370         /* STMIA r0-15, [r0] at debug speed
371          * register values will start to appear on 4th DCLK
372          */
373         arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
374
375         /* fetch NOP, STM in DECODE stage */
376         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
377         /* fetch NOP, STM in EXECUTE stage (1st cycle) */
378         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
379
380         for (i = 0; i <= 15; i++) {
381                 if (mask & (1 << i))
382                         /* nothing fetched, STM in MEMORY (i'th cycle) */
383                         arm9tdmi_clock_data_in(jtag_info, core_regs[i]);
384         }
385 }
386
387 static void arm9tdmi_read_core_regs_target_buffer(struct target *target,
388                 uint32_t mask, void *buffer, int size)
389 {
390         int i;
391         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
392         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
393         int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
394         uint32_t *buf_u32 = buffer;
395         uint16_t *buf_u16 = buffer;
396         uint8_t *buf_u8 = buffer;
397
398         /* STMIA r0-15, [r0] at debug speed
399          * register values will start to appear on 4th DCLK
400          */
401         arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
402
403         /* fetch NOP, STM in DECODE stage */
404         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
405         /* fetch NOP, STM in EXECUTE stage (1st cycle) */
406         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
407
408         for (i = 0; i <= 15; i++) {
409                 if (mask & (1 << i))
410                         /* nothing fetched, STM in MEMORY (i'th cycle) */
411                         switch (size) {
412                                 case 4:
413                                         arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
414                                         break;
415                                 case 2:
416                                         arm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
417                                         break;
418                                 case 1:
419                                         arm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
420                                         break;
421                         }
422         }
423 }
424
425 static void arm9tdmi_read_xpsr(struct target *target, uint32_t *xpsr, int spsr)
426 {
427         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
428         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
429
430         /* MRS r0, cpsr */
431         arm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0);
432         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
433         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
434         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
435         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
436
437         /* STR r0, [r15] */
438         arm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0, NULL, 0);
439         /* fetch NOP, STR in DECODE stage */
440         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
441         /* fetch NOP, STR in EXECUTE stage (1st cycle) */
442         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
443         /* nothing fetched, STR in MEMORY */
444         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0);
445 }
446
447 static void arm9tdmi_write_xpsr(struct target *target, uint32_t xpsr, int spsr)
448 {
449         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
450         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
451
452         LOG_DEBUG("xpsr: %8.8" PRIx32 ", spsr: %i", xpsr, spsr);
453
454         /* MSR1 fetched */
455         arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0);
456         /* MSR2 fetched, MSR1 in DECODE */
457         arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0);
458         /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
459         arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0);
460         /* nothing fetched, MSR1 in EXECUTE (2) */
461         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
462         /* nothing fetched, MSR1 in EXECUTE (3) */
463         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
464         /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
465         arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0);
466         /* nothing fetched, MSR2 in EXECUTE (2) */
467         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
468         /* nothing fetched, MSR2 in EXECUTE (3) */
469         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
470         /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
471         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
472         /* nothing fetched, MSR3 in EXECUTE (2) */
473         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
474         /* nothing fetched, MSR3 in EXECUTE (3) */
475         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
476         /* NOP fetched, MSR4 in EXECUTE (1) */
477         /* last MSR writes flags, which takes only one cycle */
478         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
479 }
480
481 static void arm9tdmi_write_xpsr_im8(struct target *target,
482                 uint8_t xpsr_im, int rot, int spsr)
483 {
484         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
485         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
486
487         LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
488
489         /* MSR fetched */
490         arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0);
491         /* NOP fetched, MSR in DECODE */
492         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
493         /* NOP fetched, MSR in EXECUTE (1) */
494         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
495
496         /* rot == 4 writes flags, which takes only one cycle */
497         if (rot != 4) {
498                 /* nothing fetched, MSR in EXECUTE (2) */
499                 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
500                 /* nothing fetched, MSR in EXECUTE (3) */
501                 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
502         }
503 }
504
505 void arm9tdmi_write_core_regs(struct target *target,
506                 uint32_t mask, uint32_t core_regs[16])
507 {
508         int i;
509         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
510         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
511
512         /* LDMIA r0-15, [r0] at debug speed
513         * register values will start to appear on 4th DCLK
514         */
515         arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
516
517         /* fetch NOP, LDM in DECODE stage */
518         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
519         /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
520         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
521
522         for (i = 0; i <= 15; i++) {
523                 if (mask & (1 << i))
524                         /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
525                         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0);
526         }
527         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
528 }
529
530 void arm9tdmi_load_word_regs(struct target *target, uint32_t mask)
531 {
532         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
533         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
534
535         /* put system-speed load-multiple into the pipeline */
536         arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), 0, NULL, 0);
537         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
538 }
539
540 void arm9tdmi_load_hword_reg(struct target *target, int num)
541 {
542         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
543         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
544
545         /* put system-speed load half-word into the pipeline */
546         arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), 0, NULL, 0);
547         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
548 }
549
550 void arm9tdmi_load_byte_reg(struct target *target, int num)
551 {
552         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
553         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
554
555         /* put system-speed load byte into the pipeline */
556         arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), 0, NULL, 0);
557         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
558 }
559
560 void arm9tdmi_store_word_regs(struct target *target, uint32_t mask)
561 {
562         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
563         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
564
565         /* put system-speed store-multiple into the pipeline */
566         arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), 0, NULL, 0);
567         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
568 }
569
570 void arm9tdmi_store_hword_reg(struct target *target, int num)
571 {
572         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
573         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
574
575         /* put system-speed store half-word into the pipeline */
576         arm9tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), 0, NULL, 0);
577         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
578 }
579
580 void arm9tdmi_store_byte_reg(struct target *target, int num)
581 {
582         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
583         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
584
585         /* put system-speed store byte into the pipeline */
586         arm9tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), 0, NULL, 0);
587         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
588 }
589
590 static void arm9tdmi_write_pc(struct target *target, uint32_t pc)
591 {
592         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
593         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
594
595         /* LDMIA r0-15, [r0] at debug speed
596          * register values will start to appear on 4th DCLK
597          */
598         arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL, 0);
599
600         /* fetch NOP, LDM in DECODE stage */
601         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
602         /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
603         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
604         /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
605         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, pc, NULL, 0);
606         /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
607         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
608         /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
609         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
610         /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
611         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
612 }
613
614 void arm9tdmi_branch_resume(struct target *target)
615 {
616         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
617         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
618
619         arm9tdmi_clock_out(jtag_info, ARMV4_5_B(0xfffffc, 0), 0, NULL, 0);
620         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
621 }
622
623 static void arm9tdmi_branch_resume_thumb(struct target *target)
624 {
625         LOG_DEBUG("-");
626
627         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
628         struct arm *arm = &arm7_9->arm;
629         struct arm_jtag *jtag_info = &arm7_9->jtag_info;
630         struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
631
632         /* LDMIA r0-15, [r0] at debug speed
633         * register values will start to appear on 4th DCLK
634         */
635         arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL, 0);
636
637         /* fetch NOP, LDM in DECODE stage */
638         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
639         /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
640         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
641         /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
642         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP,
643                         buf_get_u32(arm->pc->value, 0, 32) | 1, NULL, 0);
644         /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
645         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
646
647         /* Branch and eXchange */
648         arm9tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0, NULL, 0);
649
650         embeddedice_read_reg(dbg_stat);
651
652         /* fetch NOP, BX in DECODE stage */
653         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
654
655         embeddedice_read_reg(dbg_stat);
656
657         /* fetch NOP, BX in EXECUTE stage (1st cycle) */
658         arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
659
660         /* target is now in Thumb state */
661         embeddedice_read_reg(dbg_stat);
662
663         /* load r0 value, MOV_IM in Decode*/
664         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);
665         /* fetch NOP, LDR in Decode, MOV_IM in Execute */
666         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
667         /* fetch NOP, LDR in Execute */
668         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
669         /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
670         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP,
671                         buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32), NULL, 0);
672         /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
673         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
674
675         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
676         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
677
678         embeddedice_read_reg(dbg_stat);
679
680         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f7), 0, NULL, 1);
681         arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
682 }
683
684 void arm9tdmi_enable_single_step(struct target *target, uint32_t next_pc)
685 {
686         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
687
688         if (arm7_9->has_single_step) {
689                 buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 1);
690                 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
691         } else
692                 arm7_9_enable_eice_step(target, next_pc);
693 }
694
695 void arm9tdmi_disable_single_step(struct target *target)
696 {
697         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
698
699         if (arm7_9->has_single_step) {
700                 buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 0);
701                 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
702         } else
703                 arm7_9_disable_eice_step(target);
704 }
705
706 static void arm9tdmi_build_reg_cache(struct target *target)
707 {
708         struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
709         struct arm *arm = target_to_arm(target);
710
711         (*cache_p) = arm_build_reg_cache(target, arm);
712 }
713
714 int arm9tdmi_init_target(struct command_context *cmd_ctx,
715                 struct target *target)
716 {
717         arm9tdmi_build_reg_cache(target);
718         arm_semihosting_init(target);
719         return ERROR_OK;
720 }
721
722 int arm9tdmi_init_arch_info(struct target *target,
723                 struct arm7_9_common *arm7_9, struct jtag_tap *tap)
724 {
725         /* prepare JTAG information for the new target */
726         arm7_9->jtag_info.tap = tap;
727         arm7_9->jtag_info.scann_size = 5;
728
729         /* register arch-specific functions */
730         arm7_9->examine_debug_reason = arm9tdmi_examine_debug_reason;
731         arm7_9->change_to_arm = arm9tdmi_change_to_arm;
732         arm7_9->read_core_regs = arm9tdmi_read_core_regs;
733         arm7_9->read_core_regs_target_buffer = arm9tdmi_read_core_regs_target_buffer;
734         arm7_9->read_xpsr = arm9tdmi_read_xpsr;
735
736         arm7_9->write_xpsr = arm9tdmi_write_xpsr;
737         arm7_9->write_xpsr_im8 = arm9tdmi_write_xpsr_im8;
738         arm7_9->write_core_regs = arm9tdmi_write_core_regs;
739
740         arm7_9->load_word_regs = arm9tdmi_load_word_regs;
741         arm7_9->load_hword_reg = arm9tdmi_load_hword_reg;
742         arm7_9->load_byte_reg = arm9tdmi_load_byte_reg;
743
744         arm7_9->store_word_regs = arm9tdmi_store_word_regs;
745         arm7_9->store_hword_reg = arm9tdmi_store_hword_reg;
746         arm7_9->store_byte_reg = arm9tdmi_store_byte_reg;
747
748         arm7_9->write_pc = arm9tdmi_write_pc;
749         arm7_9->branch_resume = arm9tdmi_branch_resume;
750         arm7_9->branch_resume_thumb = arm9tdmi_branch_resume_thumb;
751
752         arm7_9->enable_single_step = arm9tdmi_enable_single_step;
753         arm7_9->disable_single_step = arm9tdmi_disable_single_step;
754
755         arm7_9->write_memory = arm7_9_write_memory;
756         arm7_9->bulk_write_memory = arm7_9_bulk_write_memory;
757
758         arm7_9->post_debug_entry = NULL;
759
760         arm7_9->pre_restore_context = NULL;
761
762         /* initialize arch-specific breakpoint handling */
763         arm7_9->arm_bkpt = 0xdeeedeee;
764         arm7_9->thumb_bkpt = 0xdeee;
765
766         arm7_9->dbgreq_adjust_pc = 3;
767
768         arm7_9_init_arch_info(target, arm7_9);
769
770         /* override use of DBGRQ, this is safe on ARM9TDMI */
771         arm7_9->use_dbgrq = 1;
772
773         /* all ARM9s have the vector catch register */
774         arm7_9->has_vector_catch = 1;
775
776         return ERROR_OK;
777 }
778
779 static int arm9tdmi_target_create(struct target *target, Jim_Interp *interp)
780 {
781         struct arm7_9_common *arm7_9 = calloc(1, sizeof(struct arm7_9_common));
782
783         arm9tdmi_init_arch_info(target, arm7_9, target->tap);
784         arm7_9->arm.arch = ARM_ARCH_V4;
785
786         return ERROR_OK;
787 }
788
789 void arm9tdmi_deinit_target(struct target *target)
790 {
791         struct arm *arm = target_to_arm(target);
792         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
793
794         arm7_9_deinit(target);
795         arm_free_reg_cache(arm);
796         free(arm7_9);
797 }
798
799 COMMAND_HANDLER(handle_arm9tdmi_catch_vectors_command)
800 {
801         struct target *target = get_current_target(CMD_CTX);
802         struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
803         struct reg *vector_catch;
804         uint32_t vector_catch_value;
805
806         if (!target_was_examined(target)) {
807                 LOG_ERROR("Target not examined yet");
808                 return ERROR_FAIL;
809         }
810
811         /* it's uncommon, but some ARM7 chips can support this */
812         if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC
813                         || !arm7_9->has_vector_catch) {
814                 command_print(CMD, "target doesn't have EmbeddedICE "
815                                 "with vector_catch");
816                 return ERROR_TARGET_INVALID;
817         }
818
819         vector_catch = &arm7_9->eice_cache->reg_list[EICE_VEC_CATCH];
820
821         /* read the vector catch register if necessary */
822         if (!vector_catch->valid)
823                 embeddedice_read_reg(vector_catch);
824
825         /* get the current setting */
826         vector_catch_value = buf_get_u32(vector_catch->value, 0, 8);
827
828         if (CMD_ARGC > 0) {
829                 vector_catch_value = 0x0;
830                 if (strcmp(CMD_ARGV[0], "all") == 0)
831                         vector_catch_value = 0xdf;
832                 else if (strcmp(CMD_ARGV[0], "none") == 0) {
833                         /* do nothing */
834                 } else {
835                         for (unsigned i = 0; i < CMD_ARGC; i++) {
836                                 /* go through list of vectors */
837                                 unsigned j;
838                                 for (j = 0; arm9tdmi_vectors[j].name; j++) {
839                                         if (strcmp(CMD_ARGV[i], arm9tdmi_vectors[j].name) == 0) {
840                                                 vector_catch_value |= arm9tdmi_vectors[j].value;
841                                                 break;
842                                         }
843                                 }
844
845                                 /* complain if vector wasn't found */
846                                 if (!arm9tdmi_vectors[j].name) {
847                                         command_print(CMD, "vector '%s' not found, leaving current setting unchanged", CMD_ARGV[i]);
848
849                                         /* reread current setting */
850                                         vector_catch_value = buf_get_u32(
851                                                         vector_catch->value,
852                                                         0, 8);
853                                         break;
854                                 }
855                         }
856                 }
857
858                 /* store new settings */
859                 buf_set_u32(vector_catch->value, 0, 8, vector_catch_value);
860                 embeddedice_store_reg(vector_catch);
861         }
862
863         /* output current settings */
864         for (unsigned i = 0; arm9tdmi_vectors[i].name; i++) {
865                 command_print(CMD, "%s: %s", arm9tdmi_vectors[i].name,
866                         (vector_catch_value & arm9tdmi_vectors[i].value)
867                                 ? "catch" : "don't catch");
868         }
869
870         return ERROR_OK;
871 }
872
873 static const struct command_registration arm9tdmi_exec_command_handlers[] = {
874         {
875                 .name = "vector_catch",
876                 .handler = handle_arm9tdmi_catch_vectors_command,
877                 .mode = COMMAND_EXEC,
878                 .help = "Display, after optionally updating, configuration "
879                         "of vector catch unit.",
880                 .usage = "[all|none|(reset|undef|swi|pabt|dabt|irq|fiq)*]",
881         },
882         COMMAND_REGISTRATION_DONE
883 };
884 const struct command_registration arm9tdmi_command_handlers[] = {
885         {
886                 .chain = arm7_9_command_handlers,
887         },
888         {
889                 .name = "arm9",
890                 .mode = COMMAND_ANY,
891                 .help = "arm9 command group",
892                 .usage = "",
893                 .chain = arm9tdmi_exec_command_handlers,
894         },
895         COMMAND_REGISTRATION_DONE
896 };
897
898 /** Holds methods for ARM9TDMI targets. */
899 struct target_type arm9tdmi_target = {
900         .name = "arm9tdmi",
901
902         .poll = arm7_9_poll,
903         .arch_state = arm_arch_state,
904
905         .target_request_data = arm7_9_target_request_data,
906
907         .halt = arm7_9_halt,
908         .resume = arm7_9_resume,
909         .step = arm7_9_step,
910
911         .assert_reset = arm7_9_assert_reset,
912         .deassert_reset = arm7_9_deassert_reset,
913         .soft_reset_halt = arm7_9_soft_reset_halt,
914
915         .get_gdb_arch = arm_get_gdb_arch,
916         .get_gdb_reg_list = arm_get_gdb_reg_list,
917
918         .read_memory = arm7_9_read_memory,
919         .write_memory = arm7_9_write_memory_opt,
920
921         .checksum_memory = arm_checksum_memory,
922         .blank_check_memory = arm_blank_check_memory,
923
924         .run_algorithm = armv4_5_run_algorithm,
925
926         .add_breakpoint = arm7_9_add_breakpoint,
927         .remove_breakpoint = arm7_9_remove_breakpoint,
928         .add_watchpoint = arm7_9_add_watchpoint,
929         .remove_watchpoint = arm7_9_remove_watchpoint,
930
931         .commands = arm9tdmi_command_handlers,
932         .target_create = arm9tdmi_target_create,
933         .init_target = arm9tdmi_init_target,
934         .deinit_target = arm9tdmi_deinit_target,
935         .examine = arm7_9_examine,
936         .check_reset = arm7_9_check_reset,
937 };