Paulius Zaleckas <paulius.zaleckas@gmail.com>:
[openocd.git] / src / target / fa526.c
1 /***************************************************************************
2 * Copyright (C) 2009 by Paulius Zaleckas *
3 * paulius.zaleckas@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21 /*
22 * FA526 is very similar to ARM920T with following differences:
23 *
24 * - execution pipeline is 6 steps
25 * - Unified TLB
26 * - has Branch Target Buffer
27 * - does not support reading of I/D cache contents
28 */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "arm920t.h"
35 #include "target_type.h"
36
37 int fa526_target_create(struct target_s *target, Jim_Interp *interp);
38 int fa526_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
39 int fa526_quit(void);
40
41 target_type_t fa526_target =
42 {
43 .name = "fa526",
44
45 .poll = arm7_9_poll,
46 .arch_state = arm920t_arch_state,
47
48 .target_request_data = arm7_9_target_request_data,
49
50 .halt = arm7_9_halt,
51 .resume = arm7_9_resume,
52 .step = arm7_9_step,
53
54 .assert_reset = arm7_9_assert_reset,
55 .deassert_reset = arm7_9_deassert_reset,
56 .soft_reset_halt = arm920t_soft_reset_halt,
57
58 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
59
60 .read_memory = arm920t_read_memory,
61 .write_memory = arm920t_write_memory,
62 .bulk_write_memory = arm7_9_bulk_write_memory,
63 .checksum_memory = arm7_9_checksum_memory,
64 .blank_check_memory = arm7_9_blank_check_memory,
65
66 .run_algorithm = armv4_5_run_algorithm,
67
68 .add_breakpoint = arm7_9_add_breakpoint,
69 .remove_breakpoint = arm7_9_remove_breakpoint,
70 .add_watchpoint = arm7_9_add_watchpoint,
71 .remove_watchpoint = arm7_9_remove_watchpoint,
72
73 .register_commands = arm920t_register_commands,
74 .target_create = fa526_target_create,
75 .init_target = fa526_init_target,
76 .examine = arm9tdmi_examine,
77 .quit = fa526_quit
78 };
79
80 void fa526_change_to_arm(target_t *target, uint32_t *r0, uint32_t *pc)
81 {
82 LOG_ERROR("%s: there is no Thumb state on FA526", __func__);
83 }
84
85 void fa526_read_core_regs(target_t *target, uint32_t mask, uint32_t* core_regs[16])
86 {
87 int i;
88 /* get pointers to arch-specific information */
89 armv4_5_common_t *armv4_5 = target->arch_info;
90 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
91 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
92
93 /* STMIA r0-15, [r0] at debug speed
94 * register values will start to appear on 4th DCLK
95 */
96 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
97
98 /* fetch NOP, STM in DECODE stage */
99 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
100 /* fetch NOP, STM in SHIFT stage */
101 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
102 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
103 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
104
105 for (i = 0; i <= 15; i++)
106 {
107 if (mask & (1 << i))
108 /* nothing fetched, STM in MEMORY (i'th cycle) */
109 arm9tdmi_clock_data_in(jtag_info, core_regs[i]);
110 }
111 }
112
113 void fa526_read_core_regs_target_buffer(target_t *target, uint32_t mask, void* buffer, int size)
114 {
115 int i;
116 /* get pointers to arch-specific information */
117 armv4_5_common_t *armv4_5 = target->arch_info;
118 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
119 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
120 int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
121 uint32_t *buf_u32 = buffer;
122 uint16_t *buf_u16 = buffer;
123 uint8_t *buf_u8 = buffer;
124
125 /* STMIA r0-15, [r0] at debug speed
126 * register values will start to appear on 4th DCLK
127 */
128 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
129
130 /* fetch NOP, STM in DECODE stage */
131 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
132 /* fetch NOP, STM in SHIFT stage */
133 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
134 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
135 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
136
137 for (i = 0; i <= 15; i++)
138 {
139 if (mask & (1 << i))
140 /* nothing fetched, STM in MEMORY (i'th cycle) */
141 switch (size)
142 {
143 case 4:
144 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
145 break;
146 case 2:
147 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
148 break;
149 case 1:
150 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
151 break;
152 }
153 }
154 }
155
156 void fa526_read_xpsr(target_t *target, uint32_t *xpsr, int spsr)
157 {
158 /* get pointers to arch-specific information */
159 armv4_5_common_t *armv4_5 = target->arch_info;
160 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
161 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
162
163 /* MRS r0, cpsr */
164 arm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0);
165 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
166 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
167 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
168 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
169 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
170
171 /* STR r0, [r15] */
172 arm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0, NULL, 0);
173 /* fetch NOP, STR in DECODE stage */
174 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
175 /* fetch NOP, STR in SHIFT stage */
176 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
177 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
178 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
179 /* nothing fetched, STR in MEMORY */
180 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0);
181 }
182
183 void fa526_write_xpsr(target_t *target, uint32_t xpsr, int spsr)
184 {
185 /* get pointers to arch-specific information */
186 armv4_5_common_t *armv4_5 = target->arch_info;
187 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
188 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
189
190 LOG_DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr);
191
192 /* MSR1 fetched */
193 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0);
194 /* MSR2 fetched, MSR1 in DECODE */
195 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0);
196 /* MSR3 fetched, MSR1 in SHIFT, MSR2 in DECODE */
197 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0);
198 /* MSR4 fetched, MSR1 in EXECUTE (1), MSR2 in SHIFT, MSR3 in DECODE */
199 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0);
200 /* nothing fetched, MSR1 in EXECUTE (2) */
201 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
202 /* nothing fetched, MSR1 in EXECUTE (3) */
203 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
204 /* nothing fetched, MSR2 in EXECUTE (1), MSR3 in SHIFT, MSR4 in DECODE */
205 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
206 /* nothing fetched, MSR2 in EXECUTE (2) */
207 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
208 /* nothing fetched, MSR2 in EXECUTE (3) */
209 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
210 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in SHIFT */
211 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
212 /* nothing fetched, MSR3 in EXECUTE (2) */
213 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
214 /* nothing fetched, MSR3 in EXECUTE (3) */
215 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
216 /* NOP fetched, MSR4 in EXECUTE (1) */
217 /* last MSR writes flags, which takes only one cycle */
218 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
219 }
220
221 void fa526_write_xpsr_im8(target_t *target, uint8_t xpsr_im, int rot, int spsr)
222 {
223 /* get pointers to arch-specific information */
224 armv4_5_common_t *armv4_5 = target->arch_info;
225 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
226 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
227
228 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
229
230 /* MSR fetched */
231 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0);
232 /* NOP fetched, MSR in DECODE */
233 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
234 /* NOP fetched, MSR in SHIFT */
235 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
236 /* NOP fetched, MSR in EXECUTE (1) */
237 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
238
239 /* rot == 4 writes flags, which takes only one cycle */
240 if (rot != 4)
241 {
242 /* nothing fetched, MSR in EXECUTE (2) */
243 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
244 /* nothing fetched, MSR in EXECUTE (3) */
245 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
246 }
247 }
248
249 void fa526_write_core_regs(target_t *target, uint32_t mask, uint32_t core_regs[16])
250 {
251 int i;
252 /* get pointers to arch-specific information */
253 armv4_5_common_t *armv4_5 = target->arch_info;
254 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
255 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
256
257 /* LDMIA r0-15, [r0] at debug speed
258 * register values will start to appear on 4th DCLK
259 */
260 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
261
262 /* fetch NOP, LDM in DECODE stage */
263 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
264 /* fetch NOP, LDM in SHIFT stage */
265 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
266 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
267 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
268
269 for (i = 0; i <= 15; i++)
270 {
271 if (mask & (1 << i))
272 /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
273 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0);
274 }
275 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
276 }
277
278 void fa526_write_pc(target_t *target, uint32_t pc)
279 {
280 /* get pointers to arch-specific information */
281 armv4_5_common_t *armv4_5 = target->arch_info;
282 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
283 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
284
285 /* LDMIA r0-15, [r0] at debug speed
286 * register values will start to appear on 4th DCLK
287 */
288 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL, 0);
289
290 /* fetch NOP, LDM in DECODE stage */
291 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
292 /* fetch NOP, LDM in SHIFT stage */
293 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
294 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
295 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
296 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
297 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, pc, NULL, 0);
298 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
299 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
300 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
301 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
302 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
303 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
304 }
305
306 void fa526_branch_resume_thumb(target_t *target)
307 {
308 LOG_ERROR("%s: there is no Thumb state on FA526", __func__);
309 }
310
311 int fa526_init_arch_info_2(target_t *target, arm9tdmi_common_t *arm9tdmi, jtag_tap_t *tap)
312 {
313 armv4_5_common_t *armv4_5;
314 arm7_9_common_t *arm7_9;
315
316 arm7_9 = &arm9tdmi->arm7_9_common;
317 armv4_5 = &arm7_9->armv4_5_common;
318
319 /* prepare JTAG information for the new target */
320 arm7_9->jtag_info.tap = tap;
321 arm7_9->jtag_info.scann_size = 5;
322
323 /* register arch-specific functions */
324 arm7_9->examine_debug_reason = arm9tdmi_examine_debug_reason;
325 arm7_9->change_to_arm = fa526_change_to_arm;
326 arm7_9->read_core_regs = fa526_read_core_regs;
327 arm7_9->read_core_regs_target_buffer = fa526_read_core_regs_target_buffer;
328 arm7_9->read_xpsr = fa526_read_xpsr;
329
330 arm7_9->write_xpsr = fa526_write_xpsr;
331 arm7_9->write_xpsr_im8 = fa526_write_xpsr_im8;
332 arm7_9->write_core_regs = fa526_write_core_regs;
333
334 arm7_9->load_word_regs = arm9tdmi_load_word_regs;
335 arm7_9->load_hword_reg = arm9tdmi_load_hword_reg;
336 arm7_9->load_byte_reg = arm9tdmi_load_byte_reg;
337
338 arm7_9->store_word_regs = arm9tdmi_store_word_regs;
339 arm7_9->store_hword_reg = arm9tdmi_store_hword_reg;
340 arm7_9->store_byte_reg = arm9tdmi_store_byte_reg;
341
342 arm7_9->write_pc = fa526_write_pc;
343 arm7_9->branch_resume = arm9tdmi_branch_resume;
344 arm7_9->branch_resume_thumb = fa526_branch_resume_thumb;
345
346 arm7_9->enable_single_step = arm9tdmi_enable_single_step;
347 arm7_9->disable_single_step = arm9tdmi_disable_single_step;
348
349 arm7_9->pre_debug_entry = NULL;
350 arm7_9->post_debug_entry = NULL;
351
352 arm7_9->pre_restore_context = NULL;
353 arm7_9->post_restore_context = NULL;
354
355 /* initialize arch-specific breakpoint handling */
356 arm7_9->arm_bkpt = 0xdeeedeee;
357 arm7_9->thumb_bkpt = 0xdeee;
358
359 arm7_9->dbgreq_adjust_pc = 3;
360 arm7_9->arch_info = arm9tdmi;
361
362 arm9tdmi->common_magic = ARM9TDMI_COMMON_MAGIC;
363 arm9tdmi->arch_info = NULL;
364
365 arm7_9_init_arch_info(target, arm7_9);
366
367 /* override use of DBGRQ, this is safe on ARM9TDMI */
368 arm7_9->use_dbgrq = 1;
369
370 /* all ARM9s have the vector catch register */
371 arm7_9->has_vector_catch = 1;
372
373 return ERROR_OK;
374 }
375
376 int fa526_init_arch_info(target_t *target, arm920t_common_t *arm920t, jtag_tap_t *tap)
377 {
378 arm9tdmi_common_t *arm9tdmi = &arm920t->arm9tdmi_common;
379 arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
380
381 /* initialize arm9tdmi specific info (including arm7_9 and armv4_5)
382 */
383 fa526_init_arch_info_2(target, arm9tdmi, tap);
384
385 arm9tdmi->arch_info = arm920t;
386 arm920t->common_magic = ARM920T_COMMON_MAGIC;
387
388 arm7_9->post_debug_entry = arm920t_post_debug_entry;
389 arm7_9->pre_restore_context = arm920t_pre_restore_context;
390
391 arm920t->armv4_5_mmu.armv4_5_cache.ctype = -1;
392 arm920t->armv4_5_mmu.get_ttb = arm920t_get_ttb;
393 arm920t->armv4_5_mmu.read_memory = arm7_9_read_memory;
394 arm920t->armv4_5_mmu.write_memory = arm7_9_write_memory;
395 arm920t->armv4_5_mmu.disable_mmu_caches = arm920t_disable_mmu_caches;
396 arm920t->armv4_5_mmu.enable_mmu_caches = arm920t_enable_mmu_caches;
397 arm920t->armv4_5_mmu.has_tiny_pages = 1;
398 arm920t->armv4_5_mmu.mmu_enabled = 0;
399
400 /* disabling linefills leads to lockups, so keep them enabled for now
401 * this doesn't affect correctness, but might affect timing issues, if
402 * important data is evicted from the cache during the debug session
403 * */
404 arm920t->preserve_cache = 0;
405
406 /* override hw single-step capability from ARM9TDMI */
407 arm7_9->has_single_step = 1;
408
409 return ERROR_OK;
410 }
411
412 int fa526_target_create(struct target_s *target, Jim_Interp *interp)
413 {
414 arm920t_common_t *arm920t = calloc(1,sizeof(arm920t_common_t));
415
416 fa526_init_arch_info(target, arm920t, target->tap);
417
418 return ERROR_OK;
419 }
420
421 int fa526_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
422 {
423 arm9tdmi_init_target(cmd_ctx, target);
424 return ERROR_OK;
425 }
426
427 int fa526_quit(void)
428 {
429 return ERROR_OK;
430 }

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)