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

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)