Audit and eliminate redundant #include directives in other target files.
[openocd.git] / src / target / feroceon.c
1 /***************************************************************************
2 * Copyright (C) 2008 by Marvell Semiconductors, Inc. *
3 * Written by Nicolas Pitre <nico@marvell.com> *
4 * *
5 * Copyright (C) 2008 by Hongtao Zheng *
6 * hontor@126.com *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
23
24 /*
25 * Marvell Feroceon support, including Orion and Kirkwood SOCs.
26 *
27 * The Feroceon core mimics the ARM926 ICE interface with the following
28 * differences:
29 *
30 * - the MOE (method of entry) reporting is not implemented
31 *
32 * - breakpoint/watchpoint comparator #1 is seemingly not implemented
33 *
34 * - due to a different pipeline implementation, some injected debug
35 * instruction sequences have to be somewhat different
36 *
37 * Other issues:
38 *
39 * - asserting DBGRQ doesn't work if target is looping on the undef vector
40 *
41 * - the EICE version signature in the COMMS_CTL reg is next to the flow bits
42 * not at the top, and rather meaningless due to existing discrepencies
43 *
44 * - the DCC channel is half duplex (only one FIFO for both directions) with
45 * seemingly no proper flow control.
46 */
47
48 #ifdef HAVE_CONFIG_H
49 #include "config.h"
50 #endif
51
52 #include "arm926ejs.h"
53
54
55 int feroceon_examine(struct target_s *target);
56 int feroceon_target_create(struct target_s *target, Jim_Interp *interp);
57 int feroceon_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer);
58 int feroceon_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
59 int feroceon_quit(void);
60
61 int feroceon_assert_reset(target_t *target)
62 {
63 armv4_5_common_t *armv4_5 = target->arch_info;
64 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
65 int ud = arm7_9->use_dbgrq;
66
67 arm7_9->use_dbgrq = 0;
68 if (target->reset_halt)
69 arm7_9_halt(target);
70 arm7_9->use_dbgrq = ud;
71 return arm7_9_assert_reset(target);
72 }
73
74 target_type_t feroceon_target =
75 {
76 .name = "feroceon",
77
78 .poll = arm7_9_poll,
79 .arch_state = arm926ejs_arch_state,
80
81 .target_request_data = arm7_9_target_request_data,
82
83 .halt = arm7_9_halt,
84 .resume = arm7_9_resume,
85 .step = arm7_9_step,
86
87 .assert_reset = feroceon_assert_reset,
88 .deassert_reset = arm7_9_deassert_reset,
89 .soft_reset_halt = arm926ejs_soft_reset_halt,
90
91 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
92
93 .read_memory = arm7_9_read_memory,
94 .write_memory = arm926ejs_write_memory,
95 .bulk_write_memory = feroceon_bulk_write_memory,
96 .checksum_memory = arm7_9_checksum_memory,
97 .blank_check_memory = arm7_9_blank_check_memory,
98
99 .run_algorithm = armv4_5_run_algorithm,
100
101 .add_breakpoint = arm7_9_add_breakpoint,
102 .remove_breakpoint = arm7_9_remove_breakpoint,
103 .add_watchpoint = arm7_9_add_watchpoint,
104 .remove_watchpoint = arm7_9_remove_watchpoint,
105
106 .register_commands = arm926ejs_register_commands,
107 .target_create = feroceon_target_create,
108 .init_target = feroceon_init_target,
109 .examine = feroceon_examine,
110 .quit = feroceon_quit
111 };
112
113
114 int feroceon_dummy_clock_out(arm_jtag_t *jtag_info, u32 instr)
115 {
116 scan_field_t fields[3];
117 u8 out_buf[4];
118 u8 instr_buf[4];
119 u8 sysspeed_buf = 0x0;
120
121 /* prepare buffer */
122 buf_set_u32(out_buf, 0, 32, 0);
123
124 buf_set_u32(instr_buf, 0, 32, flip_u32(instr, 32));
125
126 jtag_add_end_state(TAP_DRPAUSE);
127 arm_jtag_scann(jtag_info, 0x1);
128
129 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
130
131 fields[0].tap = jtag_info->tap;
132 fields[0].num_bits = 32;
133 fields[0].out_value = out_buf;
134
135 fields[0].in_value = NULL;
136
137
138
139
140
141 fields[1].tap = jtag_info->tap;
142 fields[1].num_bits = 3;
143 fields[1].out_value = &sysspeed_buf;
144
145 fields[1].in_value = NULL;
146
147
148
149
150
151 fields[2].tap = jtag_info->tap;
152 fields[2].num_bits = 32;
153 fields[2].out_value = instr_buf;
154
155 fields[2].in_value = NULL;
156
157
158
159
160
161 jtag_add_dr_scan(3, fields, TAP_INVALID);
162
163 /* no jtag_add_runtest(0, TAP_INVALID) here */
164
165 return ERROR_OK;
166 }
167
168 void feroceon_change_to_arm(target_t *target, u32 *r0, u32 *pc)
169 {
170 armv4_5_common_t *armv4_5 = target->arch_info;
171 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
172 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
173
174 /*
175 * save r0 before using it and put system in ARM state
176 * to allow common handling of ARM and THUMB debugging
177 */
178
179 feroceon_dummy_clock_out(jtag_info, ARMV4_5_T_NOP);
180 feroceon_dummy_clock_out(jtag_info, ARMV4_5_T_NOP);
181 feroceon_dummy_clock_out(jtag_info, ARMV4_5_T_NOP);
182
183 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
184 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
185 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
186 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, r0, 0);
187 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
188 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
189
190 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), 0, NULL, 0);
191 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
192 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
193 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
194 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, pc, 0);
195 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
196 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
197
198 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_BX(15), 0, NULL, 0);
199 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
200 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
201 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
202 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
203
204 jtag_execute_queue();
205
206 /*
207 * fix program counter:
208 * MOV R0, PC was the 7th instruction (+12)
209 * reading PC in Thumb state gives address of instruction + 4
210 */
211 *pc -= (12 + 4);
212 }
213
214 void feroceon_read_core_regs(target_t *target, u32 mask, u32* core_regs[16])
215 {
216 int i;
217 armv4_5_common_t *armv4_5 = target->arch_info;
218 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
219 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
220
221 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
222 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
223 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
224
225 for (i = 0; i <= 15; i++)
226 if (mask & (1 << i))
227 arm9tdmi_clock_data_in(jtag_info, core_regs[i]);
228
229 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
230 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
231 }
232
233 void feroceon_read_core_regs_target_buffer(target_t *target, u32 mask, void* buffer, int size)
234 {
235 int i;
236 armv4_5_common_t *armv4_5 = target->arch_info;
237 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
238 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
239 int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
240 u32 *buf_u32 = buffer;
241 u16 *buf_u16 = buffer;
242 u8 *buf_u8 = buffer;
243
244 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
245 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
246 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
247
248 for (i = 0; i <= 15; i++)
249 {
250 if (mask & (1 << i)) {
251 switch (size)
252 {
253 case 4:
254 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
255 break;
256 case 2:
257 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
258 break;
259 case 1:
260 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
261 break;
262 }
263 }
264 }
265
266 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
267 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
268 }
269
270 void feroceon_read_xpsr(target_t *target, u32 *xpsr, int spsr)
271 {
272 armv4_5_common_t *armv4_5 = target->arch_info;
273 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
274 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
275
276 arm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0);
277 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
278 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
279 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
280 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
281 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
282 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
283
284 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, 1, 0, 0), 0, NULL, 0);
285 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
286 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
287 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0);
288
289 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
290 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
291 }
292
293 void feroceon_write_xpsr(target_t *target, u32 xpsr, int spsr)
294 {
295 armv4_5_common_t *armv4_5 = target->arch_info;
296 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
297 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
298
299 LOG_DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr);
300
301 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0);
302 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
303 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
304 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
305 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
306 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
307 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
308
309 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0);
310 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
311 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
312 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
313 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
314 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
315 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
316
317 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0);
318 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
319 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
320 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
321 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
322 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
323 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
324
325 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0);
326 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
327 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
328 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
329 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
330 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
331 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
332 }
333
334 void feroceon_write_xpsr_im8(target_t *target, u8 xpsr_im, int rot, int spsr)
335 {
336 armv4_5_common_t *armv4_5 = target->arch_info;
337 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
338 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
339
340 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
341
342 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0);
343 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
344 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
345 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
346 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
347 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
348 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
349 }
350
351 void feroceon_write_core_regs(target_t *target, u32 mask, u32 core_regs[16])
352 {
353 int i;
354 armv4_5_common_t *armv4_5 = target->arch_info;
355 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
356 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
357
358 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
359 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
360 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
361
362 for (i = 0; i <= 15; i++)
363 if (mask & (1 << i))
364 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0);
365
366 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
367 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
368 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
369 }
370
371 void feroceon_branch_resume(target_t *target)
372 {
373 armv4_5_common_t *armv4_5 = target->arch_info;
374 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
375 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
376
377 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
378 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
379 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
380 arm9tdmi_clock_out(jtag_info, ARMV4_5_B(0xfffff9, 0), 0, NULL, 0);
381 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
382
383 arm7_9->need_bypass_before_restart = 1;
384 }
385
386 void feroceon_branch_resume_thumb(target_t *target)
387 {
388 LOG_DEBUG("-");
389
390 armv4_5_common_t *armv4_5 = target->arch_info;
391 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
392 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
393 u32 r0 = buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32);
394 u32 pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
395 (void)(r0); // use R0...
396
397 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
398 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
399 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
400 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
401
402 arm9tdmi_clock_out(jtag_info, 0xE28F0001, 0, NULL, 0); // add r0,pc,#1
403 arm9tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0, NULL, 0);
404 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
405 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
406
407 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDMIA(0, 0x1), 0, NULL, 0);
408 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
409 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
410
411 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, pc, NULL, 0);
412 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
413 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
414
415 pc = (pc & 2) >> 1;
416 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7e9 + pc), 0, NULL, 0);
417 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 1);
418
419 arm7_9->need_bypass_before_restart = 1;
420 }
421
422 int feroceon_read_cp15(target_t *target, u32 op1, u32 op2, u32 CRn, u32 CRm, u32 *value)
423 {
424 armv4_5_common_t *armv4_5 = target->arch_info;
425 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
426 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
427 int err;
428
429 arm9tdmi_clock_out(jtag_info, ARMV4_5_MRC(15, op1, 0, CRn, CRm, op2), 0, NULL, 0);
430 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
431 err = arm7_9_execute_sys_speed(target);
432 if (err != ERROR_OK)
433 return err;
434
435 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, 1, 0, 0), 0, NULL, 0);
436 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
437 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
438 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, value, 0);
439 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
440 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
441 return jtag_execute_queue();
442 }
443
444 int feroceon_write_cp15(target_t *target, u32 op1, u32 op2, u32 CRn, u32 CRm, u32 value)
445 {
446 armv4_5_common_t *armv4_5 = target->arch_info;
447 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
448 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
449
450 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 1, 0, 0), 0, NULL, 0);
451 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
452 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
453 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, value, NULL, 0);
454 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
455 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
456 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
457
458 arm9tdmi_clock_out(jtag_info, ARMV4_5_MCR(15, op1, 0, CRn, CRm, op2), 0, NULL, 0);
459 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
460 return arm7_9_execute_sys_speed(target);
461 }
462
463 void feroceon_set_dbgrq(target_t *target)
464 {
465 armv4_5_common_t *armv4_5 = target->arch_info;
466 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
467 reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
468
469 buf_set_u32(dbg_ctrl->value, 0, 8, 2);
470 embeddedice_store_reg(dbg_ctrl);
471 }
472
473 void feroceon_enable_single_step(target_t *target, u32 next_pc)
474 {
475 armv4_5_common_t *armv4_5 = target->arch_info;
476 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
477
478 /* set a breakpoint there */
479 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], next_pc);
480 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0);
481 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);
482 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);
483 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xf7);
484 }
485
486 void feroceon_disable_single_step(target_t *target)
487 {
488 armv4_5_common_t *armv4_5 = target->arch_info;
489 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
490
491 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE]);
492 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]);
493 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]);
494 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]);
495 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]);
496 }
497
498 int feroceon_examine_debug_reason(target_t *target)
499 {
500 /* the MOE is not implemented */
501 if (target->debug_reason != DBG_REASON_SINGLESTEP)
502 {
503 target->debug_reason = DBG_REASON_DBGRQ;
504 }
505
506 return ERROR_OK;
507 }
508
509 int feroceon_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
510 {
511 int retval;
512 armv4_5_common_t *armv4_5 = target->arch_info;
513 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
514 enum armv4_5_state core_state = armv4_5->core_state;
515 u32 x, flip, shift, save[7];
516 u32 i;
517
518 /*
519 * We can't use the dcc flow control bits, so let's transfer data
520 * with 31 bits and flip the MSB each time a new data word is sent.
521 */
522 static u32 dcc_code[] =
523 {
524 0xee115e10, /* 3: mrc p14, 0, r5, c1, c0, 0 */
525 0xe3a0301e, /* 1: mov r3, #30 */
526 0xe3a04002, /* mov r4, #2 */
527 0xee111e10, /* 2: mrc p14, 0, r1, c1, c0, 0 */
528 0xe1310005, /* teq r1, r5 */
529 0x0afffffc, /* beq 1b */
530 0xe1a05001, /* mov r5, r1 */
531 0xe1a01081, /* mov r1, r1, lsl #1 */
532 0xee112e10, /* 3: mrc p14, 0, r2, c1, c0, 0 */
533 0xe1320005, /* teq r2, r5 */
534 0x0afffffc, /* beq 3b */
535 0xe1a05002, /* mov r5, r2 */
536 0xe3c22102, /* bic r2, r2, #0x80000000 */
537 0xe1811332, /* orr r1, r1, r2, lsr r3 */
538 0xe2533001, /* subs r3, r3, #1 */
539 0xe4801004, /* str r1, [r0], #4 */
540 0xe1a01412, /* mov r1, r2, lsl r4 */
541 0xe2844001, /* add r4, r4, #1 */
542 0x4affffed, /* bmi 1b */
543 0xeafffff3, /* b 3b */
544 };
545
546 u32 dcc_size = sizeof(dcc_code);
547
548 if (!arm7_9->dcc_downloads)
549 return target->type->write_memory(target, address, 4, count, buffer);
550
551 /* regrab previously allocated working_area, or allocate a new one */
552 if (!arm7_9->dcc_working_area)
553 {
554 u8 dcc_code_buf[dcc_size];
555
556 /* make sure we have a working area */
557 if (target_alloc_working_area(target, dcc_size, &arm7_9->dcc_working_area) != ERROR_OK)
558 {
559 LOG_INFO("no working area available, falling back to memory writes");
560 return target->type->write_memory(target, address, 4, count, buffer);
561 }
562
563 /* copy target instructions to target endianness */
564 for (i = 0; i < dcc_size/4; i++)
565 target_buffer_set_u32(target, dcc_code_buf + i*4, dcc_code[i]);
566
567 /* write DCC code to working area */
568 if((retval = target->type->write_memory(target, arm7_9->dcc_working_area->address, 4, dcc_size/4, dcc_code_buf)) != ERROR_OK)
569 {
570 return retval;
571 }
572 }
573
574 /* backup clobbered processor state */
575 for (i = 0; i <= 5; i++)
576 save[i] = buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32);
577 save[i] = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
578
579 /* set up target address in r0 */
580 buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, address);
581 armv4_5->core_cache->reg_list[0].valid = 1;
582 armv4_5->core_cache->reg_list[0].dirty = 1;
583 armv4_5->core_state = ARMV4_5_STATE_ARM;
584
585 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], 0);
586 arm7_9_resume(target, 0, arm7_9->dcc_working_area->address, 1, 1);
587
588 /* send data over */
589 x = 0;
590 flip = 0;
591 shift = 1;
592 for (i = 0; i < count; i++)
593 {
594 u32 y = target_buffer_get_u32(target, buffer);
595 u32 z = (x >> 1) | (y >> shift) | (flip ^= 0x80000000);
596 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], z);
597 x = y << (32 - shift);
598 if (++shift >= 32 || i + 1 >= count)
599 {
600 z = (x >> 1) | (flip ^= 0x80000000);
601 embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], z);
602 x = 0;
603 shift = 1;
604 }
605 buffer += 4;
606 }
607
608 target_halt(target);
609 while (target->state != TARGET_HALTED)
610 target_poll(target);
611
612 /* restore target state */
613 for (i = 0; i <= 5; i++)
614 {
615 buf_set_u32(armv4_5->core_cache->reg_list[i].value, 0, 32, save[i]);
616 armv4_5->core_cache->reg_list[i].valid = 1;
617 armv4_5->core_cache->reg_list[i].dirty = 1;
618 }
619 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, save[i]);
620 armv4_5->core_cache->reg_list[15].valid = 1;
621 armv4_5->core_cache->reg_list[15].dirty = 1;
622 armv4_5->core_state = core_state;
623
624 return ERROR_OK;
625 }
626
627 int feroceon_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
628 {
629 arm9tdmi_init_target(cmd_ctx, target);
630 return ERROR_OK;
631 }
632
633 int feroceon_quit(void)
634 {
635 return ERROR_OK;
636 }
637
638 int feroceon_target_create(struct target_s *target, Jim_Interp *interp)
639 {
640 armv4_5_common_t *armv4_5;
641 arm7_9_common_t *arm7_9;
642 arm926ejs_common_t *arm926ejs = calloc(1,sizeof(arm926ejs_common_t));
643
644 arm926ejs_init_arch_info(target, arm926ejs, target->tap);
645
646 armv4_5 = target->arch_info;
647 arm7_9 = armv4_5->arch_info;
648
649 /* override some insn sequence functions */
650 arm7_9->change_to_arm = feroceon_change_to_arm;
651 arm7_9->read_core_regs = feroceon_read_core_regs;
652 arm7_9->read_core_regs_target_buffer = feroceon_read_core_regs_target_buffer;
653 arm7_9->read_xpsr = feroceon_read_xpsr;
654 arm7_9->write_xpsr = feroceon_write_xpsr;
655 arm7_9->write_xpsr_im8 = feroceon_write_xpsr_im8;
656 arm7_9->write_core_regs = feroceon_write_core_regs;
657 arm7_9->branch_resume = feroceon_branch_resume;
658 arm7_9->branch_resume_thumb = feroceon_branch_resume_thumb;
659
660 /* must be implemented with only one comparator */
661 arm7_9->enable_single_step = feroceon_enable_single_step;
662 arm7_9->disable_single_step = feroceon_disable_single_step;
663
664 /* MOE is not implemented */
665 arm7_9->examine_debug_reason = feroceon_examine_debug_reason;
666
667 /* the standard ARM926 methods don't always work (don't ask...) */
668 arm926ejs->read_cp15 = feroceon_read_cp15;
669 arm926ejs->write_cp15 = feroceon_write_cp15;
670
671 /* Note: asserting DBGRQ might not win over the undef exception.
672 If that happens then just use "arm7_9 dbgrq disable". */
673 arm7_9->use_dbgrq = 1;
674 arm7_9->set_special_dbgrq = feroceon_set_dbgrq;
675
676 /* only one working comparator */
677 arm7_9->wp_available_max = 1;
678 arm7_9->wp1_used_default = -1;
679
680 return ERROR_OK;
681 }
682
683 int feroceon_examine(struct target_s *target)
684 {
685 armv4_5_common_t *armv4_5;
686 arm7_9_common_t *arm7_9;
687 int retval;
688
689 retval = arm9tdmi_examine(target);
690 if (retval!=ERROR_OK)
691 return retval;
692
693 armv4_5 = target->arch_info;
694 arm7_9 = armv4_5->arch_info;
695
696 /* the COMMS_CTRL bits are all contiguous */
697 if (buf_get_u32(arm7_9->eice_cache->reg_list[EICE_COMMS_CTRL].value, 2, 4) != 6)
698 LOG_ERROR("unexpected Feroceon EICE version signature");
699
700 arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].size = 6;
701 arm7_9->eice_cache->reg_list[EICE_DBG_STAT].size = 5;
702 arm7_9->has_monitor_mode = 1;
703
704 /* vector catch reg is not initialized on reset */
705 embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH], 0);
706
707 /* clear monitor mode, enable comparators */
708 embeddedice_read_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
709 jtag_execute_queue();
710 buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 4, 1, 0);
711 buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 5, 1, 0);
712 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
713
714 return ERROR_OK;
715 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)