jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / target / fa526.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2009 by Paulius Zaleckas *
5 * paulius.zaleckas@gmail.com *
6 ***************************************************************************/
7
8 /*
9 * FA526 is very similar to ARM920T with following differences:
10 *
11 * - execution pipeline is 6 steps
12 * - Unified TLB
13 * - has Branch Target Buffer
14 * - does not support reading of I/D cache contents
15 */
16
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include "arm920t.h"
22 #include "target_type.h"
23 #include "arm_opcodes.h"
24
25 static void fa526_change_to_arm(struct target *target, uint32_t *r0, uint32_t *pc)
26 {
27 LOG_ERROR("%s: there is no Thumb state on FA526", __func__);
28 }
29
30 static void fa526_read_core_regs(struct target *target,
31 uint32_t mask, uint32_t *core_regs[16])
32 {
33 int i;
34 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
35 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
36
37 /* STMIA r0-15, [r0] at debug speed
38 * register values will start to appear on 4th DCLK
39 */
40 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
41
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);
48
49 for (i = 0; i <= 15; i++) {
50 if (mask & (1 << i))
51 /* nothing fetched, STM in MEMORY (i'th cycle) */
52 arm9tdmi_clock_data_in(jtag_info, core_regs[i]);
53 }
54 }
55
56 static void fa526_read_core_regs_target_buffer(struct target *target,
57 uint32_t mask, void *buffer, int size)
58 {
59 int i;
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;
66
67 /* STMIA r0-15, [r0] at debug speed
68 * register values will start to appear on 4th DCLK
69 */
70 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
71
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);
78
79 for (i = 0; i <= 15; i++) {
80 if (mask & (1 << i))
81 /* nothing fetched, STM in MEMORY (i'th cycle) */
82 switch (size) {
83 case 4:
84 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
85 break;
86 case 2:
87 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
88 break;
89 case 1:
90 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
91 break;
92 }
93 }
94 }
95
96 static void fa526_read_xpsr(struct target *target, uint32_t *xpsr, int spsr)
97 {
98 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
99 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
100
101 /* MRS r0, cpsr */
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);
108
109 /* STR r0, [r15] */
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);
119 }
120
121 static void fa526_write_xpsr(struct target *target, uint32_t xpsr, int spsr)
122 {
123 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
124 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
125
126 LOG_DEBUG("xpsr: %8.8" PRIx32 ", spsr: %i", xpsr, spsr);
127
128 /* MSR1 fetched */
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);
155 }
156
157 static void fa526_write_xpsr_im8(struct target *target,
158 uint8_t xpsr_im, int rot, int spsr)
159 {
160 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
161 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
162
163 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
164
165 /* MSR fetched */
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);
173
174 /* rot == 4 writes flags, which takes only one cycle */
175 if (rot != 4) {
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);
180 }
181 }
182
183 static void fa526_write_core_regs(struct target *target,
184 uint32_t mask, uint32_t core_regs[16])
185 {
186 int i;
187 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
188 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
189
190 /* LDMIA r0-15, [r0] at debug speed
191 * register values will start to appear on 4th DCLK
192 */
193 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
194
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);
201
202 for (i = 0; i <= 15; i++) {
203 if (mask & (1 << 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);
206 }
207 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
208 }
209
210 static void fa526_write_pc(struct target *target, uint32_t pc)
211 {
212 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
213 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
214
215 /* LDMIA r0-15, [r0] at debug speed
216 * register values will start to appear on 4th DCLK
217 */
218 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL, 0);
219
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);
234 }
235
236 static void fa526_branch_resume_thumb(struct target *target)
237 {
238 LOG_ERROR("%s: there is no Thumb state on FA526", __func__);
239 }
240
241 static int fa526_init_arch_info_2(struct target *target,
242 struct arm7_9_common *arm7_9, struct jtag_tap *tap)
243 {
244 /* prepare JTAG information for the new target */
245 arm7_9->jtag_info.tap = tap;
246 arm7_9->jtag_info.scann_size = 5;
247
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;
254
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;
258
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;
262
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;
266
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;
270
271 arm7_9->enable_single_step = arm9tdmi_enable_single_step;
272 arm7_9->disable_single_step = arm9tdmi_disable_single_step;
273
274 arm7_9->write_memory = arm920t_write_memory;
275 arm7_9->bulk_write_memory = arm7_9_bulk_write_memory;
276
277 arm7_9->post_debug_entry = NULL;
278
279 arm7_9->pre_restore_context = NULL;
280
281 /* initialize arch-specific breakpoint handling */
282 arm7_9->arm_bkpt = 0xdeeedeee;
283 arm7_9->thumb_bkpt = 0xdeee;
284
285 arm7_9->dbgreq_adjust_pc = 3;
286
287 arm7_9_init_arch_info(target, arm7_9);
288
289 /* override use of DBGRQ, this is safe on ARM9TDMI */
290 arm7_9->use_dbgrq = 1;
291
292 /* all ARM9s have the vector catch register */
293 arm7_9->has_vector_catch = 1;
294
295 return ERROR_OK;
296 }
297
298 static int fa526_init_arch_info(struct target *target,
299 struct arm920t_common *arm920t, struct jtag_tap *tap)
300 {
301 struct arm7_9_common *arm7_9 = &arm920t->arm7_9_common;
302
303 /* initialize arm7/arm9 specific info (including armv4_5) */
304 fa526_init_arch_info_2(target, arm7_9, tap);
305
306 arm920t->common_magic = ARM920T_COMMON_MAGIC;
307
308 arm7_9->post_debug_entry = arm920t_post_debug_entry;
309 arm7_9->pre_restore_context = arm920t_pre_restore_context;
310
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;
319
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
323 * */
324 arm920t->preserve_cache = 0;
325
326 /* override hw single-step capability from ARM9TDMI */
327 arm7_9->has_single_step = 1;
328
329 return ERROR_OK;
330 }
331
332 static int fa526_target_create(struct target *target, Jim_Interp *interp)
333 {
334 struct arm920t_common *arm920t = calloc(1, sizeof(struct arm920t_common));
335
336 return fa526_init_arch_info(target, arm920t, target->tap);
337 }
338
339 static void fa526_deinit_target(struct target *target)
340 {
341 struct arm *arm = target_to_arm(target);
342 struct arm920t_common *arm920t = target_to_arm920(target);
343
344 arm7_9_deinit(target);
345 arm_free_reg_cache(arm);
346 free(arm920t);
347 }
348
349 /** Holds methods for FA526 targets. */
350 struct target_type fa526_target = {
351 .name = "fa526",
352
353 .poll = arm7_9_poll,
354 .arch_state = arm920t_arch_state,
355
356 .target_request_data = arm7_9_target_request_data,
357
358 .halt = arm7_9_halt,
359 .resume = arm7_9_resume,
360 .step = arm7_9_step,
361
362 .assert_reset = arm7_9_assert_reset,
363 .deassert_reset = arm7_9_deassert_reset,
364 .soft_reset_halt = arm920t_soft_reset_halt,
365
366 .get_gdb_arch = arm_get_gdb_arch,
367 .get_gdb_reg_list = arm_get_gdb_reg_list,
368
369 .read_memory = arm920t_read_memory,
370 .write_memory = arm7_9_write_memory_opt,
371
372 .checksum_memory = arm_checksum_memory,
373 .blank_check_memory = arm_blank_check_memory,
374
375 .run_algorithm = armv4_5_run_algorithm,
376
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,
381
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,
388 };

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)