8c77986496fc4554586837fa3be23ad3fe4f1533
[openocd.git] / src / target / mips32.c
1 /***************************************************************************
2 * Copyright (C) 2008 by Spencer Oliver *
3 * spen@spen-soft.co.uk *
4 * *
5 * Copyright (C) 2008 by David T.L. Wong *
6 * *
7 * Copyright (C) 2007,2008 Øyvind Harboe *
8 * oyvind.harboe@zylin.com *
9 * *
10 * Copyright (C) 2011 by Drasko DRASKOVIC *
11 * drasko.draskovic@gmail.com *
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 * This program is distributed in the hope that it will be useful, *
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21 * GNU General Public License for more details. *
22 * *
23 * You should have received a copy of the GNU General Public License *
24 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
25 ***************************************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "mips32.h"
32 #include "breakpoints.h"
33 #include "algorithm.h"
34 #include "register.h"
35
36 static const char *mips_isa_strings[] = {
37 "MIPS32", "MIPS16"
38 };
39
40 #define MIPS32_GDB_DUMMY_FP_REG 1
41
42 /*
43 * GDB registers
44 * based on gdb-7.6.2/gdb/features/mips-{fpu,cp0,cpu}.xml
45 */
46 static const struct {
47 unsigned id;
48 const char *name;
49 enum reg_type type;
50 const char *group;
51 const char *feature;
52 int flag;
53 } mips32_regs[] = {
54 { 0, "r0", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
55 { 1, "r1", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
56 { 2, "r2", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
57 { 3, "r3", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
58 { 4, "r4", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
59 { 5, "r5", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
60 { 6, "r6", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
61 { 7, "r7", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
62 { 8, "r8", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
63 { 9, "r9", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
64 { 10, "r10", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
65 { 11, "r11", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
66 { 12, "r12", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
67 { 13, "r13", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
68 { 14, "r14", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
69 { 15, "r15", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
70 { 16, "r16", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
71 { 17, "r17", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
72 { 18, "r18", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
73 { 19, "r19", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
74 { 20, "r20", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
75 { 21, "r21", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
76 { 22, "r22", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
77 { 23, "r23", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
78 { 24, "r24", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
79 { 25, "r25", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
80 { 26, "r26", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
81 { 27, "r27", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
82 { 28, "r28", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
83 { 29, "r29", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
84 { 30, "r30", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
85 { 31, "r31", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
86 { 32, "status", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 },
87 { 33, "lo", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
88 { 34, "hi", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
89 { 35, "badvaddr", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 },
90 { 36, "cause", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 },
91 { 37, "pc", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
92
93 { 38, "f0", REG_TYPE_IEEE_SINGLE, NULL,
94 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
95 { 39, "f1", REG_TYPE_IEEE_SINGLE, NULL,
96 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
97 { 40, "f2", REG_TYPE_IEEE_SINGLE, NULL,
98 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
99 { 41, "f3", REG_TYPE_IEEE_SINGLE, NULL,
100 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
101 { 42, "f4", REG_TYPE_IEEE_SINGLE, NULL,
102 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
103 { 43, "f5", REG_TYPE_IEEE_SINGLE, NULL,
104 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
105 { 44, "f6", REG_TYPE_IEEE_SINGLE, NULL,
106 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
107 { 45, "f7", REG_TYPE_IEEE_SINGLE, NULL,
108 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
109 { 46, "f8", REG_TYPE_IEEE_SINGLE, NULL,
110 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
111 { 47, "f9", REG_TYPE_IEEE_SINGLE, NULL,
112 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
113 { 48, "f10", REG_TYPE_IEEE_SINGLE, NULL,
114 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
115 { 49, "f11", REG_TYPE_IEEE_SINGLE, NULL,
116 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
117 { 50, "f12", REG_TYPE_IEEE_SINGLE, NULL,
118 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
119 { 51, "f13", REG_TYPE_IEEE_SINGLE, NULL,
120 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
121 { 52, "f14", REG_TYPE_IEEE_SINGLE, NULL,
122 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
123 { 53, "f15", REG_TYPE_IEEE_SINGLE, NULL,
124 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
125 { 54, "f16", REG_TYPE_IEEE_SINGLE, NULL,
126 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
127 { 55, "f17", REG_TYPE_IEEE_SINGLE, NULL,
128 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
129 { 56, "f18", REG_TYPE_IEEE_SINGLE, NULL,
130 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
131 { 57, "f19", REG_TYPE_IEEE_SINGLE, NULL,
132 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
133 { 58, "f20", REG_TYPE_IEEE_SINGLE, NULL,
134 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
135 { 59, "f21", REG_TYPE_IEEE_SINGLE, NULL,
136 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
137 { 60, "f22", REG_TYPE_IEEE_SINGLE, NULL,
138 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
139 { 61, "f23", REG_TYPE_IEEE_SINGLE, NULL,
140 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
141 { 62, "f24", REG_TYPE_IEEE_SINGLE, NULL,
142 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
143 { 63, "f25", REG_TYPE_IEEE_SINGLE, NULL,
144 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
145 { 64, "f26", REG_TYPE_IEEE_SINGLE, NULL,
146 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
147 { 65, "f27", REG_TYPE_IEEE_SINGLE, NULL,
148 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
149 { 66, "f28", REG_TYPE_IEEE_SINGLE, NULL,
150 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
151 { 67, "f29", REG_TYPE_IEEE_SINGLE, NULL,
152 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
153 { 68, "f30", REG_TYPE_IEEE_SINGLE, NULL,
154 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
155 { 69, "f31", REG_TYPE_IEEE_SINGLE, NULL,
156 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
157 { 70, "fcsr", REG_TYPE_INT, "float",
158 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
159 { 71, "fir", REG_TYPE_INT, "float",
160 "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
161 };
162
163
164 #define MIPS32_NUM_REGS ARRAY_SIZE(mips32_regs)
165
166 static uint8_t mips32_gdb_dummy_fp_value[] = {0, 0, 0, 0};
167
168 static int mips32_get_core_reg(struct reg *reg)
169 {
170 int retval;
171 struct mips32_core_reg *mips32_reg = reg->arch_info;
172 struct target *target = mips32_reg->target;
173 struct mips32_common *mips32_target = target_to_mips32(target);
174
175 if (target->state != TARGET_HALTED)
176 return ERROR_TARGET_NOT_HALTED;
177
178 retval = mips32_target->read_core_reg(target, mips32_reg->num);
179
180 return retval;
181 }
182
183 static int mips32_set_core_reg(struct reg *reg, uint8_t *buf)
184 {
185 struct mips32_core_reg *mips32_reg = reg->arch_info;
186 struct target *target = mips32_reg->target;
187 uint32_t value = buf_get_u32(buf, 0, 32);
188
189 if (target->state != TARGET_HALTED)
190 return ERROR_TARGET_NOT_HALTED;
191
192 buf_set_u32(reg->value, 0, 32, value);
193 reg->dirty = 1;
194 reg->valid = 1;
195
196 return ERROR_OK;
197 }
198
199 static int mips32_read_core_reg(struct target *target, unsigned int num)
200 {
201 uint32_t reg_value;
202
203 /* get pointers to arch-specific information */
204 struct mips32_common *mips32 = target_to_mips32(target);
205
206 if (num >= MIPS32_NUM_REGS)
207 return ERROR_COMMAND_SYNTAX_ERROR;
208
209 reg_value = mips32->core_regs[num];
210 buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, reg_value);
211 mips32->core_cache->reg_list[num].valid = 1;
212 mips32->core_cache->reg_list[num].dirty = 0;
213
214 return ERROR_OK;
215 }
216
217 static int mips32_write_core_reg(struct target *target, unsigned int num)
218 {
219 uint32_t reg_value;
220
221 /* get pointers to arch-specific information */
222 struct mips32_common *mips32 = target_to_mips32(target);
223
224 if (num >= MIPS32_NUM_REGS)
225 return ERROR_COMMAND_SYNTAX_ERROR;
226
227 reg_value = buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
228 mips32->core_regs[num] = reg_value;
229 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num , reg_value);
230 mips32->core_cache->reg_list[num].valid = 1;
231 mips32->core_cache->reg_list[num].dirty = 0;
232
233 return ERROR_OK;
234 }
235
236 int mips32_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
237 int *reg_list_size, enum target_register_class reg_class)
238 {
239 /* get pointers to arch-specific information */
240 struct mips32_common *mips32 = target_to_mips32(target);
241 unsigned int i;
242
243 /* include floating point registers */
244 *reg_list_size = MIPS32_NUM_REGS;
245 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
246
247 for (i = 0; i < MIPS32_NUM_REGS; i++)
248 (*reg_list)[i] = &mips32->core_cache->reg_list[i];
249
250 return ERROR_OK;
251 }
252
253 int mips32_save_context(struct target *target)
254 {
255 unsigned int i;
256
257 /* get pointers to arch-specific information */
258 struct mips32_common *mips32 = target_to_mips32(target);
259 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
260
261 /* read core registers */
262 mips32_pracc_read_regs(ejtag_info, mips32->core_regs);
263
264 for (i = 0; i < MIPS32_NUM_REGS; i++) {
265 if (!mips32->core_cache->reg_list[i].valid)
266 mips32->read_core_reg(target, i);
267 }
268
269 return ERROR_OK;
270 }
271
272 int mips32_restore_context(struct target *target)
273 {
274 unsigned int i;
275
276 /* get pointers to arch-specific information */
277 struct mips32_common *mips32 = target_to_mips32(target);
278 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
279
280 for (i = 0; i < MIPS32_NUM_REGS; i++) {
281 if (mips32->core_cache->reg_list[i].dirty)
282 mips32->write_core_reg(target, i);
283 }
284
285 /* write core regs */
286 mips32_pracc_write_regs(ejtag_info, mips32->core_regs);
287
288 return ERROR_OK;
289 }
290
291 int mips32_arch_state(struct target *target)
292 {
293 struct mips32_common *mips32 = target_to_mips32(target);
294
295 LOG_USER("target halted in %s mode due to %s, pc: 0x%8.8" PRIx32 "",
296 mips_isa_strings[mips32->isa_mode],
297 debug_reason_name(target),
298 buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32));
299
300 return ERROR_OK;
301 }
302
303 static const struct reg_arch_type mips32_reg_type = {
304 .get = mips32_get_core_reg,
305 .set = mips32_set_core_reg,
306 };
307
308 struct reg_cache *mips32_build_reg_cache(struct target *target)
309 {
310 /* get pointers to arch-specific information */
311 struct mips32_common *mips32 = target_to_mips32(target);
312
313 int num_regs = MIPS32_NUM_REGS;
314 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
315 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
316 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
317 struct mips32_core_reg *arch_info = malloc(sizeof(struct mips32_core_reg) * num_regs);
318 struct reg_feature *feature;
319 int i;
320
321 /* Build the process context cache */
322 cache->name = "mips32 registers";
323 cache->next = NULL;
324 cache->reg_list = reg_list;
325 cache->num_regs = num_regs;
326 (*cache_p) = cache;
327 mips32->core_cache = cache;
328
329 for (i = 0; i < num_regs; i++) {
330 arch_info[i].num = mips32_regs[i].id;
331 arch_info[i].target = target;
332 arch_info[i].mips32_common = mips32;
333
334 reg_list[i].name = mips32_regs[i].name;
335 reg_list[i].size = 32;
336
337 if (mips32_regs[i].flag == MIPS32_GDB_DUMMY_FP_REG) {
338 reg_list[i].value = mips32_gdb_dummy_fp_value;
339 reg_list[i].valid = 1;
340 reg_list[i].arch_info = NULL;
341 register_init_dummy(&reg_list[i]);
342 } else {
343 reg_list[i].value = calloc(1, 4);
344 reg_list[i].valid = 0;
345 reg_list[i].type = &mips32_reg_type;
346 reg_list[i].arch_info = &arch_info[i];
347
348 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
349 if (reg_list[i].reg_data_type)
350 reg_list[i].reg_data_type->type = mips32_regs[i].type;
351 else
352 LOG_ERROR("unable to allocate reg type list");
353 }
354
355 reg_list[i].dirty = 0;
356
357 reg_list[i].group = mips32_regs[i].group;
358 reg_list[i].number = i;
359 reg_list[i].exist = true;
360 reg_list[i].caller_save = true; /* gdb defaults to true */
361
362 feature = calloc(1, sizeof(struct reg_feature));
363 if (feature) {
364 feature->name = mips32_regs[i].feature;
365 reg_list[i].feature = feature;
366 } else
367 LOG_ERROR("unable to allocate feature list");
368 }
369
370 return cache;
371 }
372
373 int mips32_init_arch_info(struct target *target, struct mips32_common *mips32, struct jtag_tap *tap)
374 {
375 target->arch_info = mips32;
376 mips32->common_magic = MIPS32_COMMON_MAGIC;
377 mips32->fast_data_area = NULL;
378
379 /* has breakpoint/watchpoint unit been scanned */
380 mips32->bp_scanned = 0;
381 mips32->data_break_list = NULL;
382
383 mips32->ejtag_info.tap = tap;
384 mips32->read_core_reg = mips32_read_core_reg;
385 mips32->write_core_reg = mips32_write_core_reg;
386
387 mips32->ejtag_info.scan_delay = MIPS32_SCAN_DELAY_LEGACY_MODE; /* Initial default value */
388 mips32->ejtag_info.mode = 0; /* Initial default value */
389
390 return ERROR_OK;
391 }
392
393 /* run to exit point. return error if exit point was not reached. */
394 static int mips32_run_and_wait(struct target *target, uint32_t entry_point,
395 int timeout_ms, uint32_t exit_point, struct mips32_common *mips32)
396 {
397 uint32_t pc;
398 int retval;
399 /* This code relies on the target specific resume() and poll()->debug_entry()
400 * sequence to write register values to the processor and the read them back */
401 retval = target_resume(target, 0, entry_point, 0, 1);
402 if (retval != ERROR_OK)
403 return retval;
404
405 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
406 /* If the target fails to halt due to the breakpoint, force a halt */
407 if (retval != ERROR_OK || target->state != TARGET_HALTED) {
408 retval = target_halt(target);
409 if (retval != ERROR_OK)
410 return retval;
411 retval = target_wait_state(target, TARGET_HALTED, 500);
412 if (retval != ERROR_OK)
413 return retval;
414 return ERROR_TARGET_TIMEOUT;
415 }
416
417 pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
418 if (exit_point && (pc != exit_point)) {
419 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
420 return ERROR_TARGET_TIMEOUT;
421 }
422
423 return ERROR_OK;
424 }
425
426 int mips32_run_algorithm(struct target *target, int num_mem_params,
427 struct mem_param *mem_params, int num_reg_params,
428 struct reg_param *reg_params, uint32_t entry_point,
429 uint32_t exit_point, int timeout_ms, void *arch_info)
430 {
431 struct mips32_common *mips32 = target_to_mips32(target);
432 struct mips32_algorithm *mips32_algorithm_info = arch_info;
433 enum mips32_isa_mode isa_mode = mips32->isa_mode;
434
435 uint32_t context[MIPS32_NUM_REGS];
436 int retval = ERROR_OK;
437
438 LOG_DEBUG("Running algorithm");
439
440 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
441 * at the exit point */
442
443 if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
444 LOG_ERROR("current target isn't a MIPS32 target");
445 return ERROR_TARGET_INVALID;
446 }
447
448 if (target->state != TARGET_HALTED) {
449 LOG_WARNING("target not halted");
450 return ERROR_TARGET_NOT_HALTED;
451 }
452
453 /* refresh core register cache */
454 for (unsigned int i = 0; i < MIPS32_NUM_REGS; i++) {
455 if (!mips32->core_cache->reg_list[i].valid)
456 mips32->read_core_reg(target, i);
457 context[i] = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);
458 }
459
460 for (int i = 0; i < num_mem_params; i++) {
461 retval = target_write_buffer(target, mem_params[i].address,
462 mem_params[i].size, mem_params[i].value);
463 if (retval != ERROR_OK)
464 return retval;
465 }
466
467 for (int i = 0; i < num_reg_params; i++) {
468 struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0);
469
470 if (!reg) {
471 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
472 return ERROR_COMMAND_SYNTAX_ERROR;
473 }
474
475 if (reg->size != reg_params[i].size) {
476 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
477 reg_params[i].reg_name);
478 return ERROR_COMMAND_SYNTAX_ERROR;
479 }
480
481 mips32_set_core_reg(reg, reg_params[i].value);
482 }
483
484 mips32->isa_mode = mips32_algorithm_info->isa_mode;
485
486 retval = mips32_run_and_wait(target, entry_point, timeout_ms, exit_point, mips32);
487
488 if (retval != ERROR_OK)
489 return retval;
490
491 for (int i = 0; i < num_mem_params; i++) {
492 if (mem_params[i].direction != PARAM_OUT) {
493 retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size,
494 mem_params[i].value);
495 if (retval != ERROR_OK)
496 return retval;
497 }
498 }
499
500 for (int i = 0; i < num_reg_params; i++) {
501 if (reg_params[i].direction != PARAM_OUT) {
502 struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0);
503 if (!reg) {
504 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
505 return ERROR_COMMAND_SYNTAX_ERROR;
506 }
507
508 if (reg->size != reg_params[i].size) {
509 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
510 reg_params[i].reg_name);
511 return ERROR_COMMAND_SYNTAX_ERROR;
512 }
513
514 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
515 }
516 }
517
518 /* restore everything we saved before */
519 for (unsigned int i = 0; i < MIPS32_NUM_REGS; i++) {
520 uint32_t regvalue;
521 regvalue = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);
522 if (regvalue != context[i]) {
523 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
524 mips32->core_cache->reg_list[i].name, context[i]);
525 buf_set_u32(mips32->core_cache->reg_list[i].value,
526 0, 32, context[i]);
527 mips32->core_cache->reg_list[i].valid = 1;
528 mips32->core_cache->reg_list[i].dirty = 1;
529 }
530 }
531
532 mips32->isa_mode = isa_mode;
533
534 return ERROR_OK;
535 }
536
537 int mips32_examine(struct target *target)
538 {
539 struct mips32_common *mips32 = target_to_mips32(target);
540
541 if (!target_was_examined(target)) {
542 target_set_examined(target);
543
544 /* we will configure later */
545 mips32->bp_scanned = 0;
546 mips32->num_inst_bpoints = 0;
547 mips32->num_data_bpoints = 0;
548 mips32->num_inst_bpoints_avail = 0;
549 mips32->num_data_bpoints_avail = 0;
550 }
551
552 return ERROR_OK;
553 }
554
555 static int mips32_configure_ibs(struct target *target)
556 {
557 struct mips32_common *mips32 = target_to_mips32(target);
558 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
559 int retval, i;
560 uint32_t bpinfo;
561
562 /* get number of inst breakpoints */
563 retval = target_read_u32(target, ejtag_info->ejtag_ibs_addr, &bpinfo);
564 if (retval != ERROR_OK)
565 return retval;
566
567 mips32->num_inst_bpoints = (bpinfo >> 24) & 0x0F;
568 mips32->num_inst_bpoints_avail = mips32->num_inst_bpoints;
569 mips32->inst_break_list = calloc(mips32->num_inst_bpoints,
570 sizeof(struct mips32_comparator));
571
572 for (i = 0; i < mips32->num_inst_bpoints; i++)
573 mips32->inst_break_list[i].reg_address =
574 ejtag_info->ejtag_iba0_addr +
575 (ejtag_info->ejtag_iba_step_size * i);
576
577 /* clear IBIS reg */
578 retval = target_write_u32(target, ejtag_info->ejtag_ibs_addr, 0);
579 return retval;
580 }
581
582 static int mips32_configure_dbs(struct target *target)
583 {
584 struct mips32_common *mips32 = target_to_mips32(target);
585 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
586 int retval, i;
587 uint32_t bpinfo;
588
589 /* get number of data breakpoints */
590 retval = target_read_u32(target, ejtag_info->ejtag_dbs_addr, &bpinfo);
591 if (retval != ERROR_OK)
592 return retval;
593
594 mips32->num_data_bpoints = (bpinfo >> 24) & 0x0F;
595 mips32->num_data_bpoints_avail = mips32->num_data_bpoints;
596 mips32->data_break_list = calloc(mips32->num_data_bpoints,
597 sizeof(struct mips32_comparator));
598
599 for (i = 0; i < mips32->num_data_bpoints; i++)
600 mips32->data_break_list[i].reg_address =
601 ejtag_info->ejtag_dba0_addr +
602 (ejtag_info->ejtag_dba_step_size * i);
603
604 /* clear DBIS reg */
605 retval = target_write_u32(target, ejtag_info->ejtag_dbs_addr, 0);
606 return retval;
607 }
608
609 int mips32_configure_break_unit(struct target *target)
610 {
611 /* get pointers to arch-specific information */
612 struct mips32_common *mips32 = target_to_mips32(target);
613 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
614 int retval;
615 uint32_t dcr;
616
617 if (mips32->bp_scanned)
618 return ERROR_OK;
619
620 /* get info about breakpoint support */
621 retval = target_read_u32(target, EJTAG_DCR, &dcr);
622 if (retval != ERROR_OK)
623 return retval;
624
625 /* EJTAG 2.0 defines IB and DB bits in IMP instead of DCR. */
626 if (ejtag_info->ejtag_version == EJTAG_VERSION_20) {
627 ejtag_info->debug_caps = dcr & EJTAG_DCR_ENM;
628 if (!(ejtag_info->impcode & EJTAG_V20_IMP_NOIB))
629 ejtag_info->debug_caps |= EJTAG_DCR_IB;
630 if (!(ejtag_info->impcode & EJTAG_V20_IMP_NODB))
631 ejtag_info->debug_caps |= EJTAG_DCR_DB;
632 } else
633 /* keep debug caps for later use */
634 ejtag_info->debug_caps = dcr & (EJTAG_DCR_ENM
635 | EJTAG_DCR_IB | EJTAG_DCR_DB);
636
637
638 if (ejtag_info->debug_caps & EJTAG_DCR_IB) {
639 retval = mips32_configure_ibs(target);
640 if (retval != ERROR_OK)
641 return retval;
642 }
643
644 if (ejtag_info->debug_caps & EJTAG_DCR_DB) {
645 retval = mips32_configure_dbs(target);
646 if (retval != ERROR_OK)
647 return retval;
648 }
649
650 /* check if target endianness settings matches debug control register */
651 if (((ejtag_info->debug_caps & EJTAG_DCR_ENM)
652 && (target->endianness == TARGET_LITTLE_ENDIAN)) ||
653 (!(ejtag_info->debug_caps & EJTAG_DCR_ENM)
654 && (target->endianness == TARGET_BIG_ENDIAN)))
655 LOG_WARNING("DCR endianness settings does not match target settings");
656
657 LOG_DEBUG("DCR 0x%" PRIx32 " numinst %i numdata %i", dcr, mips32->num_inst_bpoints,
658 mips32->num_data_bpoints);
659
660 mips32->bp_scanned = 1;
661
662 return ERROR_OK;
663 }
664
665 int mips32_enable_interrupts(struct target *target, int enable)
666 {
667 int retval;
668 int update = 0;
669 uint32_t dcr;
670
671 /* read debug control register */
672 retval = target_read_u32(target, EJTAG_DCR, &dcr);
673 if (retval != ERROR_OK)
674 return retval;
675
676 if (enable) {
677 if (!(dcr & EJTAG_DCR_INTE)) {
678 /* enable interrupts */
679 dcr |= EJTAG_DCR_INTE;
680 update = 1;
681 }
682 } else {
683 if (dcr & EJTAG_DCR_INTE) {
684 /* disable interrupts */
685 dcr &= ~EJTAG_DCR_INTE;
686 update = 1;
687 }
688 }
689
690 if (update) {
691 retval = target_write_u32(target, EJTAG_DCR, dcr);
692 if (retval != ERROR_OK)
693 return retval;
694 }
695
696 return ERROR_OK;
697 }
698
699 int mips32_checksum_memory(struct target *target, uint32_t address,
700 uint32_t count, uint32_t *checksum)
701 {
702 struct working_area *crc_algorithm;
703 struct reg_param reg_params[2];
704 struct mips32_algorithm mips32_info;
705
706 /* see contrib/loaders/checksum/mips32.s for src */
707
708 static const uint32_t mips_crc_code[] = {
709 0x248C0000, /* addiu $t4, $a0, 0 */
710 0x24AA0000, /* addiu $t2, $a1, 0 */
711 0x2404FFFF, /* addiu $a0, $zero, 0xffffffff */
712 0x10000010, /* beq $zero, $zero, ncomp */
713 0x240B0000, /* addiu $t3, $zero, 0 */
714 /* nbyte: */
715 0x81850000, /* lb $a1, ($t4) */
716 0x218C0001, /* addi $t4, $t4, 1 */
717 0x00052E00, /* sll $a1, $a1, 24 */
718 0x3C0204C1, /* lui $v0, 0x04c1 */
719 0x00852026, /* xor $a0, $a0, $a1 */
720 0x34471DB7, /* ori $a3, $v0, 0x1db7 */
721 0x00003021, /* addu $a2, $zero, $zero */
722 /* loop: */
723 0x00044040, /* sll $t0, $a0, 1 */
724 0x24C60001, /* addiu $a2, $a2, 1 */
725 0x28840000, /* slti $a0, $a0, 0 */
726 0x01074826, /* xor $t1, $t0, $a3 */
727 0x0124400B, /* movn $t0, $t1, $a0 */
728 0x28C30008, /* slti $v1, $a2, 8 */
729 0x1460FFF9, /* bne $v1, $zero, loop */
730 0x01002021, /* addu $a0, $t0, $zero */
731 /* ncomp: */
732 0x154BFFF0, /* bne $t2, $t3, nbyte */
733 0x256B0001, /* addiu $t3, $t3, 1 */
734 0x7000003F, /* sdbbp */
735 };
736
737 /* make sure we have a working area */
738 if (target_alloc_working_area(target, sizeof(mips_crc_code), &crc_algorithm) != ERROR_OK)
739 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
740
741 /* convert mips crc code into a buffer in target endianness */
742 uint8_t mips_crc_code_8[sizeof(mips_crc_code)];
743 target_buffer_set_u32_array(target, mips_crc_code_8,
744 ARRAY_SIZE(mips_crc_code), mips_crc_code);
745
746 target_write_buffer(target, crc_algorithm->address, sizeof(mips_crc_code), mips_crc_code_8);
747
748 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
749 mips32_info.isa_mode = MIPS32_ISA_MIPS32;
750
751 init_reg_param(&reg_params[0], "r4", 32, PARAM_IN_OUT);
752 buf_set_u32(reg_params[0].value, 0, 32, address);
753
754 init_reg_param(&reg_params[1], "r5", 32, PARAM_OUT);
755 buf_set_u32(reg_params[1].value, 0, 32, count);
756
757 int timeout = 20000 * (1 + (count / (1024 * 1024)));
758
759 int retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
760 crc_algorithm->address, crc_algorithm->address + (sizeof(mips_crc_code) - 4), timeout,
761 &mips32_info);
762
763 if (retval == ERROR_OK)
764 *checksum = buf_get_u32(reg_params[0].value, 0, 32);
765
766 destroy_reg_param(&reg_params[0]);
767 destroy_reg_param(&reg_params[1]);
768
769 target_free_working_area(target, crc_algorithm);
770
771 return retval;
772 }
773
774 /** Checks whether a memory region is zeroed. */
775 int mips32_blank_check_memory(struct target *target,
776 uint32_t address, uint32_t count, uint32_t *blank)
777 {
778 struct working_area *erase_check_algorithm;
779 struct reg_param reg_params[3];
780 struct mips32_algorithm mips32_info;
781
782 static const uint32_t erase_check_code[] = {
783 /* nbyte: */
784 0x80880000, /* lb $t0, ($a0) */
785 0x00C83024, /* and $a2, $a2, $t0 */
786 0x24A5FFFF, /* addiu $a1, $a1, -1 */
787 0x14A0FFFC, /* bne $a1, $zero, nbyte */
788 0x24840001, /* addiu $a0, $a0, 1 */
789 0x7000003F /* sdbbp */
790 };
791
792 /* make sure we have a working area */
793 if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK)
794 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
795
796 /* convert erase check code into a buffer in target endianness */
797 uint8_t erase_check_code_8[sizeof(erase_check_code)];
798 target_buffer_set_u32_array(target, erase_check_code_8,
799 ARRAY_SIZE(erase_check_code), erase_check_code);
800
801 target_write_buffer(target, erase_check_algorithm->address, sizeof(erase_check_code), erase_check_code_8);
802
803 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
804 mips32_info.isa_mode = MIPS32_ISA_MIPS32;
805
806 init_reg_param(&reg_params[0], "r4", 32, PARAM_OUT);
807 buf_set_u32(reg_params[0].value, 0, 32, address);
808
809 init_reg_param(&reg_params[1], "r5", 32, PARAM_OUT);
810 buf_set_u32(reg_params[1].value, 0, 32, count);
811
812 init_reg_param(&reg_params[2], "r6", 32, PARAM_IN_OUT);
813 buf_set_u32(reg_params[2].value, 0, 32, 0xff);
814
815 int retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
816 erase_check_algorithm->address,
817 erase_check_algorithm->address + (sizeof(erase_check_code) - 4),
818 10000, &mips32_info);
819
820 if (retval == ERROR_OK)
821 *blank = buf_get_u32(reg_params[2].value, 0, 32);
822
823 destroy_reg_param(&reg_params[0]);
824 destroy_reg_param(&reg_params[1]);
825 destroy_reg_param(&reg_params[2]);
826
827 target_free_working_area(target, erase_check_algorithm);
828
829 return retval;
830 }
831
832 static int mips32_verify_pointer(struct command_context *cmd_ctx,
833 struct mips32_common *mips32)
834 {
835 if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
836 command_print(cmd_ctx, "target is not an MIPS32");
837 return ERROR_TARGET_INVALID;
838 }
839 return ERROR_OK;
840 }
841
842 /**
843 * MIPS32 targets expose command interface
844 * to manipulate CP0 registers
845 */
846 COMMAND_HANDLER(mips32_handle_cp0_command)
847 {
848 int retval;
849 struct target *target = get_current_target(CMD_CTX);
850 struct mips32_common *mips32 = target_to_mips32(target);
851 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
852
853
854 retval = mips32_verify_pointer(CMD_CTX, mips32);
855 if (retval != ERROR_OK)
856 return retval;
857
858 if (target->state != TARGET_HALTED) {
859 command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
860 return ERROR_OK;
861 }
862
863 /* two or more argument, access a single register/select (write if third argument is given) */
864 if (CMD_ARGC < 2)
865 return ERROR_COMMAND_SYNTAX_ERROR;
866 else {
867 uint32_t cp0_reg, cp0_sel;
868 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
869 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
870
871 if (CMD_ARGC == 2) {
872 uint32_t value;
873
874 retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel);
875 if (retval != ERROR_OK) {
876 command_print(CMD_CTX,
877 "couldn't access reg %" PRIi32,
878 cp0_reg);
879 return ERROR_OK;
880 }
881 command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
882 cp0_reg, cp0_sel, value);
883
884 } else if (CMD_ARGC == 3) {
885 uint32_t value;
886 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
887 retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel);
888 if (retval != ERROR_OK) {
889 command_print(CMD_CTX,
890 "couldn't access cp0 reg %" PRIi32 ", select %" PRIi32,
891 cp0_reg, cp0_sel);
892 return ERROR_OK;
893 }
894 command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
895 cp0_reg, cp0_sel, value);
896 }
897 }
898
899 return ERROR_OK;
900 }
901
902 COMMAND_HANDLER(mips32_handle_scan_delay_command)
903 {
904 struct target *target = get_current_target(CMD_CTX);
905 struct mips32_common *mips32 = target_to_mips32(target);
906 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
907
908 if (CMD_ARGC == 1)
909 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], ejtag_info->scan_delay);
910 else if (CMD_ARGC > 1)
911 return ERROR_COMMAND_SYNTAX_ERROR;
912
913 command_print(CMD_CTX, "scan delay: %d nsec", ejtag_info->scan_delay);
914 if (ejtag_info->scan_delay >= MIPS32_SCAN_DELAY_LEGACY_MODE) {
915 ejtag_info->mode = 0;
916 command_print(CMD_CTX, "running in legacy mode");
917 } else {
918 ejtag_info->mode = 1;
919 command_print(CMD_CTX, "running in fast queued mode");
920 }
921
922 return ERROR_OK;
923 }
924
925 static const struct command_registration mips32_exec_command_handlers[] = {
926 {
927 .name = "cp0",
928 .handler = mips32_handle_cp0_command,
929 .mode = COMMAND_EXEC,
930 .usage = "regnum select [value]",
931 .help = "display/modify cp0 register",
932 },
933 {
934 .name = "scan_delay",
935 .handler = mips32_handle_scan_delay_command,
936 .mode = COMMAND_ANY,
937 .help = "display/set scan delay in nano seconds",
938 .usage = "[value]",
939 },
940 COMMAND_REGISTRATION_DONE
941 };
942
943 const struct command_registration mips32_command_handlers[] = {
944 {
945 .name = "mips32",
946 .mode = COMMAND_ANY,
947 .help = "mips32 command group",
948 .usage = "",
949 .chain = mips32_exec_command_handlers,
950 },
951 COMMAND_REGISTRATION_DONE
952 };

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)