mips32, convert miniprograms with code definition
[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 /* if unknown endianness defaults to little endian, 1 */
387 mips32->ejtag_info.endianness = target->endianness == TARGET_BIG_ENDIAN ? 0 : 1;
388 mips32->ejtag_info.scan_delay = MIPS32_SCAN_DELAY_LEGACY_MODE;
389 mips32->ejtag_info.mode = 0; /* Initial default value */
390 mips32->ejtag_info.isa = 0; /* isa on debug mips32, updated by poll function */
391
392 return ERROR_OK;
393 }
394
395 /* run to exit point. return error if exit point was not reached. */
396 static int mips32_run_and_wait(struct target *target, target_addr_t entry_point,
397 int timeout_ms, target_addr_t exit_point, struct mips32_common *mips32)
398 {
399 uint32_t pc;
400 int retval;
401 /* This code relies on the target specific resume() and poll()->debug_entry()
402 * sequence to write register values to the processor and the read them back */
403 retval = target_resume(target, 0, entry_point, 0, 1);
404 if (retval != ERROR_OK)
405 return retval;
406
407 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
408 /* If the target fails to halt due to the breakpoint, force a halt */
409 if (retval != ERROR_OK || target->state != TARGET_HALTED) {
410 retval = target_halt(target);
411 if (retval != ERROR_OK)
412 return retval;
413 retval = target_wait_state(target, TARGET_HALTED, 500);
414 if (retval != ERROR_OK)
415 return retval;
416 return ERROR_TARGET_TIMEOUT;
417 }
418
419 pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
420 if (exit_point && (pc != exit_point)) {
421 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
422 return ERROR_TARGET_TIMEOUT;
423 }
424
425 return ERROR_OK;
426 }
427
428 int mips32_run_algorithm(struct target *target, int num_mem_params,
429 struct mem_param *mem_params, int num_reg_params,
430 struct reg_param *reg_params, target_addr_t entry_point,
431 target_addr_t exit_point, int timeout_ms, void *arch_info)
432 {
433 struct mips32_common *mips32 = target_to_mips32(target);
434 struct mips32_algorithm *mips32_algorithm_info = arch_info;
435 enum mips32_isa_mode isa_mode = mips32->isa_mode;
436
437 uint32_t context[MIPS32_NUM_REGS];
438 int retval = ERROR_OK;
439
440 LOG_DEBUG("Running algorithm");
441
442 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
443 * at the exit point */
444
445 if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
446 LOG_ERROR("current target isn't a MIPS32 target");
447 return ERROR_TARGET_INVALID;
448 }
449
450 if (target->state != TARGET_HALTED) {
451 LOG_WARNING("target not halted");
452 return ERROR_TARGET_NOT_HALTED;
453 }
454
455 /* refresh core register cache */
456 for (unsigned int i = 0; i < MIPS32_NUM_REGS; i++) {
457 if (!mips32->core_cache->reg_list[i].valid)
458 mips32->read_core_reg(target, i);
459 context[i] = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);
460 }
461
462 for (int i = 0; i < num_mem_params; i++) {
463 retval = target_write_buffer(target, mem_params[i].address,
464 mem_params[i].size, mem_params[i].value);
465 if (retval != ERROR_OK)
466 return retval;
467 }
468
469 for (int i = 0; i < num_reg_params; i++) {
470 struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0);
471
472 if (!reg) {
473 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
474 return ERROR_COMMAND_SYNTAX_ERROR;
475 }
476
477 if (reg->size != reg_params[i].size) {
478 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
479 reg_params[i].reg_name);
480 return ERROR_COMMAND_SYNTAX_ERROR;
481 }
482
483 mips32_set_core_reg(reg, reg_params[i].value);
484 }
485
486 mips32->isa_mode = mips32_algorithm_info->isa_mode;
487
488 retval = mips32_run_and_wait(target, entry_point, timeout_ms, exit_point, mips32);
489
490 if (retval != ERROR_OK)
491 return retval;
492
493 for (int i = 0; i < num_mem_params; i++) {
494 if (mem_params[i].direction != PARAM_OUT) {
495 retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size,
496 mem_params[i].value);
497 if (retval != ERROR_OK)
498 return retval;
499 }
500 }
501
502 for (int i = 0; i < num_reg_params; i++) {
503 if (reg_params[i].direction != PARAM_OUT) {
504 struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0);
505 if (!reg) {
506 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
507 return ERROR_COMMAND_SYNTAX_ERROR;
508 }
509
510 if (reg->size != reg_params[i].size) {
511 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
512 reg_params[i].reg_name);
513 return ERROR_COMMAND_SYNTAX_ERROR;
514 }
515
516 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
517 }
518 }
519
520 /* restore everything we saved before */
521 for (unsigned int i = 0; i < MIPS32_NUM_REGS; i++) {
522 uint32_t regvalue;
523 regvalue = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);
524 if (regvalue != context[i]) {
525 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
526 mips32->core_cache->reg_list[i].name, context[i]);
527 buf_set_u32(mips32->core_cache->reg_list[i].value,
528 0, 32, context[i]);
529 mips32->core_cache->reg_list[i].valid = 1;
530 mips32->core_cache->reg_list[i].dirty = 1;
531 }
532 }
533
534 mips32->isa_mode = isa_mode;
535
536 return ERROR_OK;
537 }
538
539 int mips32_examine(struct target *target)
540 {
541 struct mips32_common *mips32 = target_to_mips32(target);
542
543 if (!target_was_examined(target)) {
544 target_set_examined(target);
545
546 /* we will configure later */
547 mips32->bp_scanned = 0;
548 mips32->num_inst_bpoints = 0;
549 mips32->num_data_bpoints = 0;
550 mips32->num_inst_bpoints_avail = 0;
551 mips32->num_data_bpoints_avail = 0;
552 }
553
554 return ERROR_OK;
555 }
556
557 static int mips32_configure_ibs(struct target *target)
558 {
559 struct mips32_common *mips32 = target_to_mips32(target);
560 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
561 int retval, i;
562 uint32_t bpinfo;
563
564 /* get number of inst breakpoints */
565 retval = target_read_u32(target, ejtag_info->ejtag_ibs_addr, &bpinfo);
566 if (retval != ERROR_OK)
567 return retval;
568
569 mips32->num_inst_bpoints = (bpinfo >> 24) & 0x0F;
570 mips32->num_inst_bpoints_avail = mips32->num_inst_bpoints;
571 mips32->inst_break_list = calloc(mips32->num_inst_bpoints,
572 sizeof(struct mips32_comparator));
573
574 for (i = 0; i < mips32->num_inst_bpoints; i++)
575 mips32->inst_break_list[i].reg_address =
576 ejtag_info->ejtag_iba0_addr +
577 (ejtag_info->ejtag_iba_step_size * i);
578
579 /* clear IBIS reg */
580 retval = target_write_u32(target, ejtag_info->ejtag_ibs_addr, 0);
581 return retval;
582 }
583
584 static int mips32_configure_dbs(struct target *target)
585 {
586 struct mips32_common *mips32 = target_to_mips32(target);
587 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
588 int retval, i;
589 uint32_t bpinfo;
590
591 /* get number of data breakpoints */
592 retval = target_read_u32(target, ejtag_info->ejtag_dbs_addr, &bpinfo);
593 if (retval != ERROR_OK)
594 return retval;
595
596 mips32->num_data_bpoints = (bpinfo >> 24) & 0x0F;
597 mips32->num_data_bpoints_avail = mips32->num_data_bpoints;
598 mips32->data_break_list = calloc(mips32->num_data_bpoints,
599 sizeof(struct mips32_comparator));
600
601 for (i = 0; i < mips32->num_data_bpoints; i++)
602 mips32->data_break_list[i].reg_address =
603 ejtag_info->ejtag_dba0_addr +
604 (ejtag_info->ejtag_dba_step_size * i);
605
606 /* clear DBIS reg */
607 retval = target_write_u32(target, ejtag_info->ejtag_dbs_addr, 0);
608 return retval;
609 }
610
611 int mips32_configure_break_unit(struct target *target)
612 {
613 /* get pointers to arch-specific information */
614 struct mips32_common *mips32 = target_to_mips32(target);
615 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
616 int retval;
617 uint32_t dcr;
618
619 if (mips32->bp_scanned)
620 return ERROR_OK;
621
622 /* get info about breakpoint support */
623 retval = target_read_u32(target, EJTAG_DCR, &dcr);
624 if (retval != ERROR_OK)
625 return retval;
626
627 /* EJTAG 2.0 defines IB and DB bits in IMP instead of DCR. */
628 if (ejtag_info->ejtag_version == EJTAG_VERSION_20) {
629 ejtag_info->debug_caps = dcr & EJTAG_DCR_ENM;
630 if (!(ejtag_info->impcode & EJTAG_V20_IMP_NOIB))
631 ejtag_info->debug_caps |= EJTAG_DCR_IB;
632 if (!(ejtag_info->impcode & EJTAG_V20_IMP_NODB))
633 ejtag_info->debug_caps |= EJTAG_DCR_DB;
634 } else
635 /* keep debug caps for later use */
636 ejtag_info->debug_caps = dcr & (EJTAG_DCR_ENM
637 | EJTAG_DCR_IB | EJTAG_DCR_DB);
638
639
640 if (ejtag_info->debug_caps & EJTAG_DCR_IB) {
641 retval = mips32_configure_ibs(target);
642 if (retval != ERROR_OK)
643 return retval;
644 }
645
646 if (ejtag_info->debug_caps & EJTAG_DCR_DB) {
647 retval = mips32_configure_dbs(target);
648 if (retval != ERROR_OK)
649 return retval;
650 }
651
652 /* check if target endianness settings matches debug control register */
653 if (((ejtag_info->debug_caps & EJTAG_DCR_ENM)
654 && (target->endianness == TARGET_LITTLE_ENDIAN)) ||
655 (!(ejtag_info->debug_caps & EJTAG_DCR_ENM)
656 && (target->endianness == TARGET_BIG_ENDIAN)))
657 LOG_WARNING("DCR endianness settings does not match target settings");
658
659 LOG_DEBUG("DCR 0x%" PRIx32 " numinst %i numdata %i", dcr, mips32->num_inst_bpoints,
660 mips32->num_data_bpoints);
661
662 mips32->bp_scanned = 1;
663
664 return ERROR_OK;
665 }
666
667 int mips32_enable_interrupts(struct target *target, int enable)
668 {
669 int retval;
670 int update = 0;
671 uint32_t dcr;
672
673 /* read debug control register */
674 retval = target_read_u32(target, EJTAG_DCR, &dcr);
675 if (retval != ERROR_OK)
676 return retval;
677
678 if (enable) {
679 if (!(dcr & EJTAG_DCR_INTE)) {
680 /* enable interrupts */
681 dcr |= EJTAG_DCR_INTE;
682 update = 1;
683 }
684 } else {
685 if (dcr & EJTAG_DCR_INTE) {
686 /* disable interrupts */
687 dcr &= ~EJTAG_DCR_INTE;
688 update = 1;
689 }
690 }
691
692 if (update) {
693 retval = target_write_u32(target, EJTAG_DCR, dcr);
694 if (retval != ERROR_OK)
695 return retval;
696 }
697
698 return ERROR_OK;
699 }
700
701 int mips32_checksum_memory(struct target *target, target_addr_t address,
702 uint32_t count, uint32_t *checksum)
703 {
704 struct working_area *crc_algorithm;
705 struct reg_param reg_params[2];
706 struct mips32_algorithm mips32_info;
707
708 struct mips32_common *mips32 = target_to_mips32(target);
709 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
710
711 /* see contrib/loaders/checksum/mips32.s for src */
712 uint32_t isa = ejtag_info->isa ? 1 : 0;
713
714 uint32_t mips_crc_code[] = {
715 MIPS32_ADDIU(isa, 12, 4, 0), /* addiu $t4, $a0, 0 */
716 MIPS32_ADDIU(isa, 10, 5, 0), /* addiu $t2, $a1, 0 */
717 MIPS32_ADDIU(isa, 4, 0, 0xFFFF), /* addiu $a0, $zero, 0xffff */
718 MIPS32_BEQ(isa, 0, 0, 0x10 << isa), /* beq $zero, $zero, ncomp */
719 MIPS32_ADDIU(isa, 11, 0, 0), /* addiu $t3, $zero, 0 */
720 /* nbyte: */
721 MIPS32_LB(isa, 5, 0, 12), /* lb $a1, ($t4) */
722 MIPS32_ADDI(isa, 12, 12, 1), /* addi $t4, $t4, 1 */
723 MIPS32_SLL(isa, 5, 5, 24), /* sll $a1, $a1, 24 */
724 MIPS32_LUI(isa, 2, 0x04c1), /* lui $v0, 0x04c1 */
725 MIPS32_XOR(isa, 4, 4, 5), /* xor $a0, $a0, $a1 */
726 MIPS32_ORI(isa, 7, 2, 0x1db7), /* ori $a3, $v0, 0x1db7 */
727 MIPS32_ADDU(isa, 6, 0, 0), /* addu $a2, $zero, $zero */
728 /* loop */
729 MIPS32_SLL(isa, 8, 4, 1), /* sll $t0, $a0, 1 */
730 MIPS32_ADDIU(isa, 6, 6, 1), /* addiu $a2, $a2, 1 */
731 MIPS32_SLTI(isa, 4, 4, 0), /* slti $a0, $a0, 0 */
732 MIPS32_XOR(isa, 9, 8, 7), /* xor $t1, $t0, $a3 */
733 MIPS32_MOVN(isa, 8, 9, 4), /* movn $t0, $t1, $a0 */
734 MIPS32_SLTI(isa, 3, 6, 8), /* slti $v1, $a2, 8 */
735 MIPS32_BNE(isa, 3, 0, NEG16(7 << isa)), /* bne $v1, $zero, loop */
736 MIPS32_ADDU(isa, 4, 8, 0), /* addu $a0, $t0, $zero */
737 /* ncomp */
738 MIPS32_BNE(isa, 10, 11, NEG16(16 << isa)), /* bne $t2, $t3, nbyte */
739 MIPS32_ADDIU(isa, 11, 11, 1), /* addiu $t3, $t3, 1 */
740 MIPS32_SDBBP(isa),
741 };
742
743 /* make sure we have a working area */
744 if (target_alloc_working_area(target, sizeof(mips_crc_code), &crc_algorithm) != ERROR_OK)
745 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
746
747 pracc_swap16_array(ejtag_info, mips_crc_code, ARRAY_SIZE(mips_crc_code));
748
749 /* convert mips crc code into a buffer in target endianness */
750 uint8_t mips_crc_code_8[sizeof(mips_crc_code)];
751 target_buffer_set_u32_array(target, mips_crc_code_8,
752 ARRAY_SIZE(mips_crc_code), mips_crc_code);
753
754 int retval = target_write_buffer(target, crc_algorithm->address, sizeof(mips_crc_code), mips_crc_code_8);
755 if (retval != ERROR_OK)
756 return retval;
757
758 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
759 mips32_info.isa_mode = MIPS32_ISA_MIPS32;
760
761 init_reg_param(&reg_params[0], "r4", 32, PARAM_IN_OUT);
762 buf_set_u32(reg_params[0].value, 0, 32, address);
763
764 init_reg_param(&reg_params[1], "r5", 32, PARAM_OUT);
765 buf_set_u32(reg_params[1].value, 0, 32, count);
766
767 int timeout = 20000 * (1 + (count / (1024 * 1024)));
768
769 /* same isa as in debug mode */
770 retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
771 crc_algorithm->address | isa,
772 (crc_algorithm->address + (sizeof(mips_crc_code) - 4)) | isa,
773 timeout, &mips32_info);
774
775 if (retval == ERROR_OK)
776 *checksum = buf_get_u32(reg_params[0].value, 0, 32);
777
778 destroy_reg_param(&reg_params[0]);
779 destroy_reg_param(&reg_params[1]);
780
781 target_free_working_area(target, crc_algorithm);
782
783 return retval;
784 }
785
786 /** Checks whether a memory region is erased. */
787 int mips32_blank_check_memory(struct target *target,
788 target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value)
789 {
790 struct working_area *erase_check_algorithm;
791 struct reg_param reg_params[3];
792 struct mips32_algorithm mips32_info;
793
794 struct mips32_common *mips32 = target_to_mips32(target);
795 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
796
797 if (erased_value != 0xff) {
798 LOG_ERROR("Erase value 0x%02" PRIx8 " not yet supported for MIPS32",
799 erased_value);
800 return ERROR_FAIL;
801 }
802 uint32_t isa = ejtag_info->isa ? 1 : 0;
803 uint32_t erase_check_code[] = {
804 /* nbyte: */
805 MIPS32_LB(isa, 8, 0, 4), /* lb $t0, ($a0) */
806 MIPS32_AND(isa, 6, 6, 8), /* and $a2, $a2, $t0 */
807 MIPS32_ADDIU(isa, 5, 5, NEG16(1)), /* addiu $a1, $a1, -1 */
808 MIPS32_BNE(isa, 5, 0, NEG16(4 << isa)), /* bne $a1, $zero, nbyte */
809 MIPS32_ADDIU(isa, 4, 4, 1), /* addiu $a0, $a0, 1 */
810 MIPS32_SDBBP(isa) /* sdbbp */
811 };
812
813 /* make sure we have a working area */
814 if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK)
815 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
816
817 pracc_swap16_array(ejtag_info, erase_check_code, ARRAY_SIZE(erase_check_code));
818
819 /* convert erase check code into a buffer in target endianness */
820 uint8_t erase_check_code_8[sizeof(erase_check_code)];
821 target_buffer_set_u32_array(target, erase_check_code_8,
822 ARRAY_SIZE(erase_check_code), erase_check_code);
823
824 int retval = target_write_buffer(target, erase_check_algorithm->address,
825 sizeof(erase_check_code), erase_check_code_8);
826 if (retval != ERROR_OK)
827 return retval;
828
829 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
830 mips32_info.isa_mode = MIPS32_ISA_MIPS32;
831
832 init_reg_param(&reg_params[0], "r4", 32, PARAM_OUT);
833 buf_set_u32(reg_params[0].value, 0, 32, address);
834
835 init_reg_param(&reg_params[1], "r5", 32, PARAM_OUT);
836 buf_set_u32(reg_params[1].value, 0, 32, count);
837
838 init_reg_param(&reg_params[2], "r6", 32, PARAM_IN_OUT);
839 buf_set_u32(reg_params[2].value, 0, 32, erased_value);
840
841 /* same isa as in debug mode */
842 retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
843 erase_check_algorithm->address | isa,
844 (erase_check_algorithm->address + (sizeof(erase_check_code) - 4)) | isa,
845 10000, &mips32_info);
846
847 if (retval == ERROR_OK)
848 *blank = buf_get_u32(reg_params[2].value, 0, 32);
849
850 destroy_reg_param(&reg_params[0]);
851 destroy_reg_param(&reg_params[1]);
852 destroy_reg_param(&reg_params[2]);
853
854 target_free_working_area(target, erase_check_algorithm);
855
856 return retval;
857 }
858
859 static int mips32_verify_pointer(struct command_context *cmd_ctx,
860 struct mips32_common *mips32)
861 {
862 if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
863 command_print(cmd_ctx, "target is not an MIPS32");
864 return ERROR_TARGET_INVALID;
865 }
866 return ERROR_OK;
867 }
868
869 /**
870 * MIPS32 targets expose command interface
871 * to manipulate CP0 registers
872 */
873 COMMAND_HANDLER(mips32_handle_cp0_command)
874 {
875 int retval;
876 struct target *target = get_current_target(CMD_CTX);
877 struct mips32_common *mips32 = target_to_mips32(target);
878 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
879
880
881 retval = mips32_verify_pointer(CMD_CTX, mips32);
882 if (retval != ERROR_OK)
883 return retval;
884
885 if (target->state != TARGET_HALTED) {
886 command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
887 return ERROR_OK;
888 }
889
890 /* two or more argument, access a single register/select (write if third argument is given) */
891 if (CMD_ARGC < 2)
892 return ERROR_COMMAND_SYNTAX_ERROR;
893 else {
894 uint32_t cp0_reg, cp0_sel;
895 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
896 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
897
898 if (CMD_ARGC == 2) {
899 uint32_t value;
900
901 retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel);
902 if (retval != ERROR_OK) {
903 command_print(CMD_CTX,
904 "couldn't access reg %" PRIi32,
905 cp0_reg);
906 return ERROR_OK;
907 }
908 command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
909 cp0_reg, cp0_sel, value);
910
911 } else if (CMD_ARGC == 3) {
912 uint32_t value;
913 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
914 retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel);
915 if (retval != ERROR_OK) {
916 command_print(CMD_CTX,
917 "couldn't access cp0 reg %" PRIi32 ", select %" PRIi32,
918 cp0_reg, cp0_sel);
919 return ERROR_OK;
920 }
921 command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
922 cp0_reg, cp0_sel, value);
923 }
924 }
925
926 return ERROR_OK;
927 }
928
929 COMMAND_HANDLER(mips32_handle_scan_delay_command)
930 {
931 struct target *target = get_current_target(CMD_CTX);
932 struct mips32_common *mips32 = target_to_mips32(target);
933 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
934
935 if (CMD_ARGC == 1)
936 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], ejtag_info->scan_delay);
937 else if (CMD_ARGC > 1)
938 return ERROR_COMMAND_SYNTAX_ERROR;
939
940 command_print(CMD_CTX, "scan delay: %d nsec", ejtag_info->scan_delay);
941 if (ejtag_info->scan_delay >= MIPS32_SCAN_DELAY_LEGACY_MODE) {
942 ejtag_info->mode = 0;
943 command_print(CMD_CTX, "running in legacy mode");
944 } else {
945 ejtag_info->mode = 1;
946 command_print(CMD_CTX, "running in fast queued mode");
947 }
948
949 return ERROR_OK;
950 }
951
952 static const struct command_registration mips32_exec_command_handlers[] = {
953 {
954 .name = "cp0",
955 .handler = mips32_handle_cp0_command,
956 .mode = COMMAND_EXEC,
957 .usage = "regnum select [value]",
958 .help = "display/modify cp0 register",
959 },
960 {
961 .name = "scan_delay",
962 .handler = mips32_handle_scan_delay_command,
963 .mode = COMMAND_ANY,
964 .help = "display/set scan delay in nano seconds",
965 .usage = "[value]",
966 },
967 COMMAND_REGISTRATION_DONE
968 };
969
970 const struct command_registration mips32_command_handlers[] = {
971 {
972 .name = "mips32",
973 .mode = COMMAND_ANY,
974 .help = "mips32 command group",
975 .usage = "",
976 .chain = mips32_exec_command_handlers,
977 },
978 COMMAND_REGISTRATION_DONE
979 };

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)