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

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)