1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2009 by Paulius Zaleckas *
5 * paulius.zaleckas@gmail.com *
6 ***************************************************************************/
9 * FA526 is very similar to ARM920T with following differences:
11 * - execution pipeline is 6 steps
13 * - has Branch Target Buffer
14 * - does not support reading of I/D cache contents
22 #include "target_type.h"
23 #include "arm_opcodes.h"
25 static void fa526_change_to_arm(struct target
*target
, uint32_t *r0
, uint32_t *pc
)
27 LOG_ERROR("%s: there is no Thumb state on FA526", __func__
);
30 static void fa526_read_core_regs(struct target
*target
,
31 uint32_t mask
, uint32_t *core_regs
[16])
34 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
35 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
37 /* STMIA r0-15, [r0] at debug speed
38 * register values will start to appear on 4th DCLK
40 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
42 /* fetch NOP, STM in DECODE stage */
43 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
44 /* fetch NOP, STM in SHIFT stage */
45 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
46 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
47 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
49 for (i
= 0; i
<= 15; i
++) {
51 /* nothing fetched, STM in MEMORY (i'th cycle) */
52 arm9tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
56 static void fa526_read_core_regs_target_buffer(struct target
*target
,
57 uint32_t mask
, void *buffer
, int size
)
60 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
61 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
62 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
63 uint32_t *buf_u32
= buffer
;
64 uint16_t *buf_u16
= buffer
;
65 uint8_t *buf_u8
= buffer
;
67 /* STMIA r0-15, [r0] at debug speed
68 * register values will start to appear on 4th DCLK
70 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
72 /* fetch NOP, STM in DECODE stage */
73 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
74 /* fetch NOP, STM in SHIFT stage */
75 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
76 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
77 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
79 for (i
= 0; i
<= 15; i
++) {
81 /* nothing fetched, STM in MEMORY (i'th cycle) */
84 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
87 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
90 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
96 static void fa526_read_xpsr(struct target
*target
, uint32_t *xpsr
, int spsr
)
98 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
99 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
102 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), 0, NULL
, 0);
103 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
104 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
105 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
106 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
107 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
110 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), 0, NULL
, 0);
111 /* fetch NOP, STR in DECODE stage */
112 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
113 /* fetch NOP, STR in SHIFT stage */
114 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
115 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
116 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
117 /* nothing fetched, STR in MEMORY */
118 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, xpsr
, 0);
121 static void fa526_write_xpsr(struct target
*target
, uint32_t xpsr
, int spsr
)
123 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
124 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
126 LOG_DEBUG("xpsr: %8.8" PRIx32
", spsr: %i", xpsr
, spsr
);
129 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), 0, NULL
, 0);
130 /* MSR2 fetched, MSR1 in DECODE */
131 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), 0, NULL
, 0);
132 /* MSR3 fetched, MSR1 in SHIFT, MSR2 in DECODE */
133 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), 0, NULL
, 0);
134 /* MSR4 fetched, MSR1 in EXECUTE (1), MSR2 in SHIFT, MSR3 in DECODE */
135 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), 0, NULL
, 0);
136 /* nothing fetched, MSR1 in EXECUTE (2) */
137 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
138 /* nothing fetched, MSR1 in EXECUTE (3) */
139 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
140 /* nothing fetched, MSR2 in EXECUTE (1), MSR3 in SHIFT, MSR4 in DECODE */
141 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
142 /* nothing fetched, MSR2 in EXECUTE (2) */
143 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
144 /* nothing fetched, MSR2 in EXECUTE (3) */
145 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
146 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in SHIFT */
147 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
148 /* nothing fetched, MSR3 in EXECUTE (2) */
149 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
150 /* nothing fetched, MSR3 in EXECUTE (3) */
151 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
152 /* NOP fetched, MSR4 in EXECUTE (1) */
153 /* last MSR writes flags, which takes only one cycle */
154 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
157 static void fa526_write_xpsr_im8(struct target
*target
,
158 uint8_t xpsr_im
, int rot
, int spsr
)
160 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
161 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
163 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im
, rot
, spsr
);
166 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr_im
, rot
, 1, spsr
), 0, NULL
, 0);
167 /* NOP fetched, MSR in DECODE */
168 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
169 /* NOP fetched, MSR in SHIFT */
170 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
171 /* NOP fetched, MSR in EXECUTE (1) */
172 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
174 /* rot == 4 writes flags, which takes only one cycle */
176 /* nothing fetched, MSR in EXECUTE (2) */
177 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
178 /* nothing fetched, MSR in EXECUTE (3) */
179 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
183 static void fa526_write_core_regs(struct target
*target
,
184 uint32_t mask
, uint32_t core_regs
[16])
187 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
188 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
190 /* LDMIA r0-15, [r0] at debug speed
191 * register values will start to appear on 4th DCLK
193 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
195 /* fetch NOP, LDM in DECODE stage */
196 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
197 /* fetch NOP, LDM in SHIFT stage */
198 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
199 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
200 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
202 for (i
= 0; i
<= 15; i
++) {
204 /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
205 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, core_regs
[i
], NULL
, 0);
207 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
210 static void fa526_write_pc(struct target
*target
, uint32_t pc
)
212 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
213 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
215 /* LDMIA r0-15, [r0] at debug speed
216 * register values will start to appear on 4th DCLK
218 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL
, 0);
220 /* fetch NOP, LDM in DECODE stage */
221 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
222 /* fetch NOP, LDM in SHIFT stage */
223 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
224 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
225 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
226 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
227 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, pc
, NULL
, 0);
228 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
229 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
230 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
231 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
232 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
233 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
236 static void fa526_branch_resume_thumb(struct target
*target
)
238 LOG_ERROR("%s: there is no Thumb state on FA526", __func__
);
241 static int fa526_init_arch_info_2(struct target
*target
,
242 struct arm7_9_common
*arm7_9
, struct jtag_tap
*tap
)
244 /* prepare JTAG information for the new target */
245 arm7_9
->jtag_info
.tap
= tap
;
246 arm7_9
->jtag_info
.scann_size
= 5;
248 /* register arch-specific functions */
249 arm7_9
->examine_debug_reason
= arm9tdmi_examine_debug_reason
;
250 arm7_9
->change_to_arm
= fa526_change_to_arm
;
251 arm7_9
->read_core_regs
= fa526_read_core_regs
;
252 arm7_9
->read_core_regs_target_buffer
= fa526_read_core_regs_target_buffer
;
253 arm7_9
->read_xpsr
= fa526_read_xpsr
;
255 arm7_9
->write_xpsr
= fa526_write_xpsr
;
256 arm7_9
->write_xpsr_im8
= fa526_write_xpsr_im8
;
257 arm7_9
->write_core_regs
= fa526_write_core_regs
;
259 arm7_9
->load_word_regs
= arm9tdmi_load_word_regs
;
260 arm7_9
->load_hword_reg
= arm9tdmi_load_hword_reg
;
261 arm7_9
->load_byte_reg
= arm9tdmi_load_byte_reg
;
263 arm7_9
->store_word_regs
= arm9tdmi_store_word_regs
;
264 arm7_9
->store_hword_reg
= arm9tdmi_store_hword_reg
;
265 arm7_9
->store_byte_reg
= arm9tdmi_store_byte_reg
;
267 arm7_9
->write_pc
= fa526_write_pc
;
268 arm7_9
->branch_resume
= arm9tdmi_branch_resume
;
269 arm7_9
->branch_resume_thumb
= fa526_branch_resume_thumb
;
271 arm7_9
->enable_single_step
= arm9tdmi_enable_single_step
;
272 arm7_9
->disable_single_step
= arm9tdmi_disable_single_step
;
274 arm7_9
->write_memory
= arm920t_write_memory
;
275 arm7_9
->bulk_write_memory
= arm7_9_bulk_write_memory
;
277 arm7_9
->post_debug_entry
= NULL
;
279 arm7_9
->pre_restore_context
= NULL
;
281 /* initialize arch-specific breakpoint handling */
282 arm7_9
->arm_bkpt
= 0xdeeedeee;
283 arm7_9
->thumb_bkpt
= 0xdeee;
285 arm7_9
->dbgreq_adjust_pc
= 3;
287 arm7_9_init_arch_info(target
, arm7_9
);
289 /* override use of DBGRQ, this is safe on ARM9TDMI */
290 arm7_9
->use_dbgrq
= 1;
292 /* all ARM9s have the vector catch register */
293 arm7_9
->has_vector_catch
= 1;
298 static int fa526_init_arch_info(struct target
*target
,
299 struct arm920t_common
*arm920t
, struct jtag_tap
*tap
)
301 struct arm7_9_common
*arm7_9
= &arm920t
->arm7_9_common
;
303 /* initialize arm7/arm9 specific info (including armv4_5) */
304 fa526_init_arch_info_2(target
, arm7_9
, tap
);
306 arm920t
->common_magic
= ARM920T_COMMON_MAGIC
;
308 arm7_9
->post_debug_entry
= arm920t_post_debug_entry
;
309 arm7_9
->pre_restore_context
= arm920t_pre_restore_context
;
311 arm920t
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
312 arm920t
->armv4_5_mmu
.get_ttb
= arm920t_get_ttb
;
313 arm920t
->armv4_5_mmu
.read_memory
= arm7_9_read_memory
;
314 arm920t
->armv4_5_mmu
.write_memory
= arm7_9_write_memory
;
315 arm920t
->armv4_5_mmu
.disable_mmu_caches
= arm920t_disable_mmu_caches
;
316 arm920t
->armv4_5_mmu
.enable_mmu_caches
= arm920t_enable_mmu_caches
;
317 arm920t
->armv4_5_mmu
.has_tiny_pages
= 1;
318 arm920t
->armv4_5_mmu
.mmu_enabled
= 0;
320 /* disabling linefills leads to lockups, so keep them enabled for now
321 * this doesn't affect correctness, but might affect timing issues, if
322 * important data is evicted from the cache during the debug session
324 arm920t
->preserve_cache
= 0;
326 /* override hw single-step capability from ARM9TDMI */
327 arm7_9
->has_single_step
= 1;
332 static int fa526_target_create(struct target
*target
, Jim_Interp
*interp
)
334 struct arm920t_common
*arm920t
= calloc(1, sizeof(struct arm920t_common
));
336 return fa526_init_arch_info(target
, arm920t
, target
->tap
);
339 static void fa526_deinit_target(struct target
*target
)
341 struct arm
*arm
= target_to_arm(target
);
342 struct arm920t_common
*arm920t
= target_to_arm920(target
);
344 arm7_9_deinit(target
);
345 arm_free_reg_cache(arm
);
349 /** Holds methods for FA526 targets. */
350 struct target_type fa526_target
= {
354 .arch_state
= arm920t_arch_state
,
356 .target_request_data
= arm7_9_target_request_data
,
359 .resume
= arm7_9_resume
,
362 .assert_reset
= arm7_9_assert_reset
,
363 .deassert_reset
= arm7_9_deassert_reset
,
364 .soft_reset_halt
= arm920t_soft_reset_halt
,
366 .get_gdb_arch
= arm_get_gdb_arch
,
367 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
369 .read_memory
= arm920t_read_memory
,
370 .write_memory
= arm7_9_write_memory_opt
,
372 .checksum_memory
= arm_checksum_memory
,
373 .blank_check_memory
= arm_blank_check_memory
,
375 .run_algorithm
= armv4_5_run_algorithm
,
377 .add_breakpoint
= arm7_9_add_breakpoint
,
378 .remove_breakpoint
= arm7_9_remove_breakpoint
,
379 .add_watchpoint
= arm7_9_add_watchpoint
,
380 .remove_watchpoint
= arm7_9_remove_watchpoint
,
382 .commands
= arm920t_command_handlers
,
383 .target_create
= fa526_target_create
,
384 .init_target
= arm9tdmi_init_target
,
385 .deinit_target
= fa526_deinit_target
,
386 .examine
= arm7_9_examine
,
387 .check_reset
= arm7_9_check_reset
,
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)