1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2008 by Spencer Oliver *
5 * spen@spen-soft.co.uk *
7 * Copyright (C) 2008 by David T.L. Wong *
9 * Copyright (C) 2007,2008 Øyvind Harboe *
10 * oyvind.harboe@zylin.com *
12 * Copyright (C) 2011 by Drasko DRASKOVIC *
13 * drasko.draskovic@gmail.com *
14 ***************************************************************************/
22 #include "breakpoints.h"
23 #include "algorithm.h"
26 static const char *mips_isa_strings
[] = {
27 "MIPS32", "MIPS16", "", "MICRO MIPS32",
30 #define MIPS32_GDB_FP_REG 1
34 * based on gdb-7.6.2/gdb/features/mips-{fpu,cp0,cpu}.xml
44 { 0, "r0", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
45 { 1, "r1", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
46 { 2, "r2", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
47 { 3, "r3", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
48 { 4, "r4", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
49 { 5, "r5", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
50 { 6, "r6", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
51 { 7, "r7", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
52 { 8, "r8", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
53 { 9, "r9", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
54 { 10, "r10", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
55 { 11, "r11", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
56 { 12, "r12", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
57 { 13, "r13", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
58 { 14, "r14", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
59 { 15, "r15", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
60 { 16, "r16", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
61 { 17, "r17", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
62 { 18, "r18", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
63 { 19, "r19", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
64 { 20, "r20", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
65 { 21, "r21", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
66 { 22, "r22", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
67 { 23, "r23", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
68 { 24, "r24", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
69 { 25, "r25", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
70 { 26, "r26", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
71 { 27, "r27", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
72 { 28, "r28", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
73 { 29, "r29", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
74 { 30, "r30", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
75 { 31, "r31", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
76 { 32, "lo", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
77 { 33, "hi", REG_TYPE_INT
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
79 { MIPS32_REGLIST_FP_INDEX
+ 0, "f0", REG_TYPE_IEEE_DOUBLE
, NULL
,
80 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
81 { MIPS32_REGLIST_FP_INDEX
+ 1, "f1", REG_TYPE_IEEE_DOUBLE
, NULL
,
82 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
83 { MIPS32_REGLIST_FP_INDEX
+ 2, "f2", REG_TYPE_IEEE_DOUBLE
, NULL
,
84 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
85 { MIPS32_REGLIST_FP_INDEX
+ 3, "f3", REG_TYPE_IEEE_DOUBLE
, NULL
,
86 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
87 { MIPS32_REGLIST_FP_INDEX
+ 4, "f4", REG_TYPE_IEEE_DOUBLE
, NULL
,
88 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
89 { MIPS32_REGLIST_FP_INDEX
+ 5, "f5", REG_TYPE_IEEE_DOUBLE
, NULL
,
90 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
91 { MIPS32_REGLIST_FP_INDEX
+ 6, "f6", REG_TYPE_IEEE_DOUBLE
, NULL
,
92 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
93 { MIPS32_REGLIST_FP_INDEX
+ 7, "f7", REG_TYPE_IEEE_DOUBLE
, NULL
,
94 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
95 { MIPS32_REGLIST_FP_INDEX
+ 8, "f8", REG_TYPE_IEEE_DOUBLE
, NULL
,
96 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
97 { MIPS32_REGLIST_FP_INDEX
+ 9, "f9", REG_TYPE_IEEE_DOUBLE
, NULL
,
98 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
99 { MIPS32_REGLIST_FP_INDEX
+ 10, "f10", REG_TYPE_IEEE_DOUBLE
, NULL
,
100 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
101 { MIPS32_REGLIST_FP_INDEX
+ 11, "f11", REG_TYPE_IEEE_DOUBLE
, NULL
,
102 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
103 { MIPS32_REGLIST_FP_INDEX
+ 12, "f12", REG_TYPE_IEEE_DOUBLE
, NULL
,
104 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
105 { MIPS32_REGLIST_FP_INDEX
+ 13, "f13", REG_TYPE_IEEE_DOUBLE
, NULL
,
106 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
107 { MIPS32_REGLIST_FP_INDEX
+ 14, "f14", REG_TYPE_IEEE_DOUBLE
, NULL
,
108 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
109 { MIPS32_REGLIST_FP_INDEX
+ 15, "f15", REG_TYPE_IEEE_DOUBLE
, NULL
,
110 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
111 { MIPS32_REGLIST_FP_INDEX
+ 16, "f16", REG_TYPE_IEEE_DOUBLE
, NULL
,
112 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
113 { MIPS32_REGLIST_FP_INDEX
+ 17, "f17", REG_TYPE_IEEE_DOUBLE
, NULL
,
114 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
115 { MIPS32_REGLIST_FP_INDEX
+ 18, "f18", REG_TYPE_IEEE_DOUBLE
, NULL
,
116 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
117 { MIPS32_REGLIST_FP_INDEX
+ 19, "f19", REG_TYPE_IEEE_DOUBLE
, NULL
,
118 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
119 { MIPS32_REGLIST_FP_INDEX
+ 20, "f20", REG_TYPE_IEEE_DOUBLE
, NULL
,
120 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
121 { MIPS32_REGLIST_FP_INDEX
+ 21, "f21", REG_TYPE_IEEE_DOUBLE
, NULL
,
122 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
123 { MIPS32_REGLIST_FP_INDEX
+ 22, "f22", REG_TYPE_IEEE_DOUBLE
, NULL
,
124 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
125 { MIPS32_REGLIST_FP_INDEX
+ 23, "f23", REG_TYPE_IEEE_DOUBLE
, NULL
,
126 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
127 { MIPS32_REGLIST_FP_INDEX
+ 24, "f24", REG_TYPE_IEEE_DOUBLE
, NULL
,
128 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
129 { MIPS32_REGLIST_FP_INDEX
+ 25, "f25", REG_TYPE_IEEE_DOUBLE
, NULL
,
130 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
131 { MIPS32_REGLIST_FP_INDEX
+ 26, "f26", REG_TYPE_IEEE_DOUBLE
, NULL
,
132 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
133 { MIPS32_REGLIST_FP_INDEX
+ 27, "f27", REG_TYPE_IEEE_DOUBLE
, NULL
,
134 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
135 { MIPS32_REGLIST_FP_INDEX
+ 28, "f28", REG_TYPE_IEEE_DOUBLE
, NULL
,
136 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
137 { MIPS32_REGLIST_FP_INDEX
+ 29, "f29", REG_TYPE_IEEE_DOUBLE
, NULL
,
138 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
139 { MIPS32_REGLIST_FP_INDEX
+ 30, "f30", REG_TYPE_IEEE_DOUBLE
, NULL
,
140 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
141 { MIPS32_REGLIST_FP_INDEX
+ 31, "f31", REG_TYPE_IEEE_DOUBLE
, NULL
,
142 "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG
},
144 { MIPS32_REGLIST_FPC_INDEX
+ 0, "fcsr", REG_TYPE_INT
, "float",
145 "org.gnu.gdb.mips.fpu", 0 },
146 { MIPS32_REGLIST_FPC_INDEX
+ 1, "fir", REG_TYPE_INT
, "float",
147 "org.gnu.gdb.mips.fpu", 0 },
149 { MIPS32_REGLIST_C0_STATUS_INDEX
, "status", REG_TYPE_INT
, NULL
,
150 "org.gnu.gdb.mips.cp0", 0 },
151 { MIPS32_REGLIST_C0_BADVADDR_INDEX
, "badvaddr", REG_TYPE_INT
, NULL
,
152 "org.gnu.gdb.mips.cp0", 0 },
153 { MIPS32_REGLIST_C0_CAUSE_INDEX
, "cause", REG_TYPE_INT
, NULL
,
154 "org.gnu.gdb.mips.cp0", 0 },
155 { MIPS32_REGLIST_C0_PC_INDEX
, "pc", REG_TYPE_INT
, NULL
,
156 "org.gnu.gdb.mips.cpu", 0 },
157 { MIPS32_REGLIST_C0_GUESTCTL1_INDEX
, "guestCtl1", REG_TYPE_INT
, NULL
,
158 "org.gnu.gdb.mips.cp0", 0 },
161 #define MIPS32_NUM_REGS ARRAY_SIZE(mips32_regs)
163 static int mips32_get_core_reg(struct reg
*reg
)
166 struct mips32_core_reg
*mips32_reg
= reg
->arch_info
;
167 struct target
*target
= mips32_reg
->target
;
168 struct mips32_common
*mips32_target
= target_to_mips32(target
);
170 if (target
->state
!= TARGET_HALTED
)
171 return ERROR_TARGET_NOT_HALTED
;
173 retval
= mips32_target
->read_core_reg(target
, mips32_reg
->num
);
178 static int mips32_set_core_reg(struct reg
*reg
, uint8_t *buf
)
180 struct mips32_core_reg
*mips32_reg
= reg
->arch_info
;
181 struct target
*target
= mips32_reg
->target
;
185 value
= buf_get_u64(buf
, 0, 64);
187 value
= buf_get_u32(buf
, 0, 32);
189 if (target
->state
!= TARGET_HALTED
)
190 return ERROR_TARGET_NOT_HALTED
;
193 buf_set_u64(reg
->value
, 0, 64, value
);
195 buf_set_u32(reg
->value
, 0, 32, value
);
203 static int mips32_read_core_reg(struct target
*target
, unsigned int num
)
206 uint64_t reg_value
= 0;
208 /* get pointers to arch-specific information */
209 struct mips32_common
*mips32
= target_to_mips32(target
);
211 if (num
>= MIPS32_NUM_REGS
)
212 return ERROR_COMMAND_SYNTAX_ERROR
;
214 if (num
>= MIPS32_REGLIST_C0_INDEX
) {
216 cnum
= num
- MIPS32_REGLIST_C0_INDEX
;
217 reg_value
= mips32
->core_regs
.cp0
[cnum
];
218 buf_set_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
219 } else if (num
>= MIPS32_REGLIST_FPC_INDEX
) {
221 cnum
= num
- MIPS32_REGLIST_FPC_INDEX
;
222 reg_value
= mips32
->core_regs
.fpcr
[cnum
];
223 buf_set_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
224 } else if (num
>= MIPS32_REGLIST_FP_INDEX
) {
226 cnum
= num
- MIPS32_REGLIST_FP_INDEX
;
227 reg_value
= mips32
->core_regs
.fpr
[cnum
];
228 buf_set_u64(mips32
->core_cache
->reg_list
[num
].value
, 0, 64, reg_value
);
231 cnum
= num
- MIPS32_REGLIST_GP_INDEX
;
232 reg_value
= mips32
->core_regs
.gpr
[cnum
];
233 buf_set_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
236 mips32
->core_cache
->reg_list
[num
].valid
= true;
237 mips32
->core_cache
->reg_list
[num
].dirty
= false;
239 LOG_DEBUG("read core reg %i value 0x%" PRIx64
"", num
, reg_value
);
244 static int mips32_write_core_reg(struct target
*target
, unsigned int num
)
249 /* get pointers to arch-specific information */
250 struct mips32_common
*mips32
= target_to_mips32(target
);
252 if (num
>= MIPS32_NUM_REGS
)
253 return ERROR_COMMAND_SYNTAX_ERROR
;
255 if (num
>= MIPS32_REGLIST_C0_INDEX
) {
257 cnum
= num
- MIPS32_REGLIST_C0_INDEX
;
258 reg_value
= buf_get_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32);
259 mips32
->core_regs
.cp0
[cnum
] = (uint32_t)reg_value
;
260 } else if (num
>= MIPS32_REGLIST_FPC_INDEX
) {
262 cnum
= num
- MIPS32_REGLIST_FPC_INDEX
;
263 reg_value
= buf_get_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32);
264 mips32
->core_regs
.fpcr
[cnum
] = (uint32_t)reg_value
;
265 } else if (num
>= MIPS32_REGLIST_FP_INDEX
) {
267 cnum
= num
- MIPS32_REGLIST_FP_INDEX
;
268 reg_value
= buf_get_u64(mips32
->core_cache
->reg_list
[num
].value
, 0, 64);
269 mips32
->core_regs
.fpr
[cnum
] = reg_value
;
272 cnum
= num
- MIPS32_REGLIST_GP_INDEX
;
273 reg_value
= buf_get_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32);
274 mips32
->core_regs
.gpr
[cnum
] = (uint32_t)reg_value
;
277 LOG_DEBUG("write core reg %i value 0x%" PRIx64
"", num
, reg_value
);
278 mips32
->core_cache
->reg_list
[num
].valid
= true;
279 mips32
->core_cache
->reg_list
[num
].dirty
= false;
284 int mips32_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
285 int *reg_list_size
, enum target_register_class reg_class
)
287 /* get pointers to arch-specific information */
288 struct mips32_common
*mips32
= target_to_mips32(target
);
291 /* include floating point registers */
292 *reg_list_size
= MIPS32_NUM_REGS
;
293 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
295 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++)
296 (*reg_list
)[i
] = &mips32
->core_cache
->reg_list
[i
];
301 int mips32_save_context(struct target
*target
)
305 /* get pointers to arch-specific information */
306 struct mips32_common
*mips32
= target_to_mips32(target
);
308 /* read core registers */
309 int retval
= mips32_pracc_read_regs(mips32
);
310 if (retval
!= ERROR_OK
) {
311 LOG_ERROR("Could not read core registers from target");
315 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
316 if (!mips32
->core_cache
->reg_list
[i
].valid
)
317 mips32
->read_core_reg(target
, i
);
323 int mips32_restore_context(struct target
*target
)
327 /* get pointers to arch-specific information */
328 struct mips32_common
*mips32
= target_to_mips32(target
);
330 for (i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
331 if (mips32
->core_cache
->reg_list
[i
].dirty
)
332 mips32
->write_core_reg(target
, i
);
335 /* write core regs */
336 mips32_pracc_write_regs(mips32
);
341 int mips32_arch_state(struct target
*target
)
343 struct mips32_common
*mips32
= target_to_mips32(target
);
345 LOG_USER("target halted in %s mode due to %s, pc: 0x%8.8" PRIx32
"",
346 mips_isa_strings
[mips32
->isa_mode
],
347 debug_reason_name(target
),
348 buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_REGLIST_C0_PC_INDEX
].value
, 0, 32));
353 static const struct reg_arch_type mips32_reg_type
= {
354 .get
= mips32_get_core_reg
,
355 .set
= mips32_set_core_reg
,
358 struct reg_cache
*mips32_build_reg_cache(struct target
*target
)
360 /* get pointers to arch-specific information */
361 struct mips32_common
*mips32
= target_to_mips32(target
);
363 int num_regs
= MIPS32_NUM_REGS
;
364 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
365 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
366 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
367 struct mips32_core_reg
*arch_info
= malloc(sizeof(struct mips32_core_reg
) * num_regs
);
368 struct reg_feature
*feature
;
371 /* Build the process context cache */
372 cache
->name
= "mips32 registers";
374 cache
->reg_list
= reg_list
;
375 cache
->num_regs
= num_regs
;
377 mips32
->core_cache
= cache
;
379 for (i
= 0; i
< num_regs
; i
++) {
380 arch_info
[i
].num
= mips32_regs
[i
].id
;
381 arch_info
[i
].target
= target
;
382 arch_info
[i
].mips32_common
= mips32
;
384 reg_list
[i
].name
= mips32_regs
[i
].name
;
385 reg_list
[i
].size
= mips32_regs
[i
].size
? 64 : 32;
387 reg_list
[i
].value
= mips32_regs
[i
].size
? calloc(1, 8) : calloc(1, 4);
388 reg_list
[i
].valid
= false;
389 reg_list
[i
].type
= &mips32_reg_type
;
390 reg_list
[i
].arch_info
= &arch_info
[i
];
392 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
393 if (reg_list
[i
].reg_data_type
)
394 reg_list
[i
].reg_data_type
->type
= mips32_regs
[i
].type
;
396 LOG_ERROR("unable to allocate reg type list");
399 reg_list
[i
].dirty
= false;
401 reg_list
[i
].group
= mips32_regs
[i
].group
;
402 reg_list
[i
].number
= i
;
403 reg_list
[i
].exist
= true;
404 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
406 feature
= calloc(1, sizeof(struct reg_feature
));
408 feature
->name
= mips32_regs
[i
].feature
;
409 reg_list
[i
].feature
= feature
;
411 LOG_ERROR("unable to allocate feature list");
417 int mips32_init_arch_info(struct target
*target
, struct mips32_common
*mips32
, struct jtag_tap
*tap
)
419 target
->arch_info
= mips32
;
420 mips32
->common_magic
= MIPS32_COMMON_MAGIC
;
421 mips32
->fast_data_area
= NULL
;
422 mips32
->isa_imp
= MIPS32_ONLY
; /* default */
424 /* has breakpoint/watchpoint unit been scanned */
425 mips32
->bp_scanned
= 0;
426 mips32
->data_break_list
= NULL
;
428 mips32
->ejtag_info
.tap
= tap
;
429 mips32
->read_core_reg
= mips32_read_core_reg
;
430 mips32
->write_core_reg
= mips32_write_core_reg
;
431 /* if unknown endianness defaults to little endian, 1 */
432 mips32
->ejtag_info
.endianness
= target
->endianness
== TARGET_BIG_ENDIAN
? 0 : 1;
433 mips32
->ejtag_info
.scan_delay
= MIPS32_SCAN_DELAY_LEGACY_MODE
;
434 mips32
->ejtag_info
.mode
= 0; /* Initial default value */
435 mips32
->ejtag_info
.isa
= 0; /* isa on debug mips32, updated by poll function */
436 mips32
->ejtag_info
.config_regs
= 0; /* no config register read */
440 /* run to exit point. return error if exit point was not reached. */
441 static int mips32_run_and_wait(struct target
*target
, target_addr_t entry_point
,
442 unsigned int timeout_ms
, target_addr_t exit_point
, struct mips32_common
*mips32
)
446 /* This code relies on the target specific resume() and poll()->debug_entry()
447 * sequence to write register values to the processor and the read them back */
448 retval
= target_resume(target
, 0, entry_point
, 0, 1);
449 if (retval
!= ERROR_OK
)
452 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
453 /* If the target fails to halt due to the breakpoint, force a halt */
454 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
) {
455 retval
= target_halt(target
);
456 if (retval
!= ERROR_OK
)
458 retval
= target_wait_state(target
, TARGET_HALTED
, 500);
459 if (retval
!= ERROR_OK
)
461 return ERROR_TARGET_TIMEOUT
;
464 pc
= buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_REGLIST_C0_PC_INDEX
].value
, 0, 32);
465 if (exit_point
&& (pc
!= exit_point
)) {
466 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32
" ", pc
);
467 return ERROR_TARGET_TIMEOUT
;
473 int mips32_run_algorithm(struct target
*target
, int num_mem_params
,
474 struct mem_param
*mem_params
, int num_reg_params
,
475 struct reg_param
*reg_params
, target_addr_t entry_point
,
476 target_addr_t exit_point
, unsigned int timeout_ms
, void *arch_info
)
478 struct mips32_common
*mips32
= target_to_mips32(target
);
479 struct mips32_algorithm
*mips32_algorithm_info
= arch_info
;
480 enum mips32_isa_mode isa_mode
= mips32
->isa_mode
;
482 uint32_t context
[MIPS32_NUM_REGS
];
483 int retval
= ERROR_OK
;
485 LOG_DEBUG("Running algorithm");
487 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
488 * at the exit point */
490 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
491 LOG_ERROR("current target isn't a MIPS32 target");
492 return ERROR_TARGET_INVALID
;
495 if (target
->state
!= TARGET_HALTED
) {
496 LOG_TARGET_ERROR(target
, "not halted (run target algo)");
497 return ERROR_TARGET_NOT_HALTED
;
500 /* refresh core register cache */
501 for (unsigned int i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
502 if (!mips32
->core_cache
->reg_list
[i
].valid
)
503 mips32
->read_core_reg(target
, i
);
504 context
[i
] = buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
507 for (int i
= 0; i
< num_mem_params
; i
++) {
508 if (mem_params
[i
].direction
== PARAM_IN
)
510 retval
= target_write_buffer(target
, mem_params
[i
].address
,
511 mem_params
[i
].size
, mem_params
[i
].value
);
512 if (retval
!= ERROR_OK
)
516 for (int i
= 0; i
< num_reg_params
; i
++) {
517 if (reg_params
[i
].direction
== PARAM_IN
)
520 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, false);
523 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
524 return ERROR_COMMAND_SYNTAX_ERROR
;
527 if (reg
->size
!= reg_params
[i
].size
) {
528 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
529 reg_params
[i
].reg_name
);
530 return ERROR_COMMAND_SYNTAX_ERROR
;
533 mips32_set_core_reg(reg
, reg_params
[i
].value
);
536 mips32
->isa_mode
= mips32_algorithm_info
->isa_mode
;
538 retval
= mips32_run_and_wait(target
, entry_point
, timeout_ms
, exit_point
, mips32
);
540 if (retval
!= ERROR_OK
)
543 for (int i
= 0; i
< num_mem_params
; i
++) {
544 if (mem_params
[i
].direction
!= PARAM_OUT
) {
545 retval
= target_read_buffer(target
, mem_params
[i
].address
, mem_params
[i
].size
,
546 mem_params
[i
].value
);
547 if (retval
!= ERROR_OK
)
552 for (int i
= 0; i
< num_reg_params
; i
++) {
553 if (reg_params
[i
].direction
!= PARAM_OUT
) {
554 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, false);
556 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
557 return ERROR_COMMAND_SYNTAX_ERROR
;
560 if (reg
->size
!= reg_params
[i
].size
) {
561 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
562 reg_params
[i
].reg_name
);
563 return ERROR_COMMAND_SYNTAX_ERROR
;
566 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
570 /* restore everything we saved before */
571 for (unsigned int i
= 0; i
< MIPS32_NUM_REGS
; i
++) {
573 regvalue
= buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
574 if (regvalue
!= context
[i
]) {
575 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
576 mips32
->core_cache
->reg_list
[i
].name
, context
[i
]);
577 buf_set_u32(mips32
->core_cache
->reg_list
[i
].value
,
579 mips32
->core_cache
->reg_list
[i
].valid
= true;
580 mips32
->core_cache
->reg_list
[i
].dirty
= true;
584 mips32
->isa_mode
= isa_mode
;
589 int mips32_examine(struct target
*target
)
591 struct mips32_common
*mips32
= target_to_mips32(target
);
593 if (!target_was_examined(target
)) {
594 target_set_examined(target
);
596 /* we will configure later */
597 mips32
->bp_scanned
= 0;
598 mips32
->num_inst_bpoints
= 0;
599 mips32
->num_data_bpoints
= 0;
600 mips32
->num_inst_bpoints_avail
= 0;
601 mips32
->num_data_bpoints_avail
= 0;
607 static int mips32_configure_ibs(struct target
*target
)
609 struct mips32_common
*mips32
= target_to_mips32(target
);
610 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
614 /* get number of inst breakpoints */
615 retval
= target_read_u32(target
, ejtag_info
->ejtag_ibs_addr
, &bpinfo
);
616 if (retval
!= ERROR_OK
)
619 mips32
->num_inst_bpoints
= (bpinfo
>> 24) & 0x0F;
620 mips32
->num_inst_bpoints_avail
= mips32
->num_inst_bpoints
;
621 mips32
->inst_break_list
= calloc(mips32
->num_inst_bpoints
,
622 sizeof(struct mips32_comparator
));
624 for (i
= 0; i
< mips32
->num_inst_bpoints
; i
++)
625 mips32
->inst_break_list
[i
].reg_address
=
626 ejtag_info
->ejtag_iba0_addr
+
627 (ejtag_info
->ejtag_iba_step_size
* i
);
630 retval
= target_write_u32(target
, ejtag_info
->ejtag_ibs_addr
, 0);
634 static int mips32_configure_dbs(struct target
*target
)
636 struct mips32_common
*mips32
= target_to_mips32(target
);
637 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
641 /* get number of data breakpoints */
642 retval
= target_read_u32(target
, ejtag_info
->ejtag_dbs_addr
, &bpinfo
);
643 if (retval
!= ERROR_OK
)
646 mips32
->num_data_bpoints
= (bpinfo
>> 24) & 0x0F;
647 mips32
->num_data_bpoints_avail
= mips32
->num_data_bpoints
;
648 mips32
->data_break_list
= calloc(mips32
->num_data_bpoints
,
649 sizeof(struct mips32_comparator
));
651 for (i
= 0; i
< mips32
->num_data_bpoints
; i
++)
652 mips32
->data_break_list
[i
].reg_address
=
653 ejtag_info
->ejtag_dba0_addr
+
654 (ejtag_info
->ejtag_dba_step_size
* i
);
657 retval
= target_write_u32(target
, ejtag_info
->ejtag_dbs_addr
, 0);
661 int mips32_configure_break_unit(struct target
*target
)
663 /* get pointers to arch-specific information */
664 struct mips32_common
*mips32
= target_to_mips32(target
);
665 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
669 if (mips32
->bp_scanned
)
672 /* get info about breakpoint support */
673 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
674 if (retval
!= ERROR_OK
)
677 /* EJTAG 2.0 defines IB and DB bits in IMP instead of DCR. */
678 if (ejtag_info
->ejtag_version
== EJTAG_VERSION_20
) {
679 ejtag_info
->debug_caps
= dcr
& EJTAG_DCR_ENM
;
680 if (!(ejtag_info
->impcode
& EJTAG_V20_IMP_NOIB
))
681 ejtag_info
->debug_caps
|= EJTAG_DCR_IB
;
682 if (!(ejtag_info
->impcode
& EJTAG_V20_IMP_NODB
))
683 ejtag_info
->debug_caps
|= EJTAG_DCR_DB
;
685 /* keep debug caps for later use */
686 ejtag_info
->debug_caps
= dcr
& (EJTAG_DCR_ENM
687 | EJTAG_DCR_IB
| EJTAG_DCR_DB
);
690 if (ejtag_info
->debug_caps
& EJTAG_DCR_IB
) {
691 retval
= mips32_configure_ibs(target
);
692 if (retval
!= ERROR_OK
)
696 if (ejtag_info
->debug_caps
& EJTAG_DCR_DB
) {
697 retval
= mips32_configure_dbs(target
);
698 if (retval
!= ERROR_OK
)
702 /* check if target endianness settings matches debug control register */
703 if (((ejtag_info
->debug_caps
& EJTAG_DCR_ENM
)
704 && (target
->endianness
== TARGET_LITTLE_ENDIAN
)) ||
705 (!(ejtag_info
->debug_caps
& EJTAG_DCR_ENM
)
706 && (target
->endianness
== TARGET_BIG_ENDIAN
)))
707 LOG_WARNING("DCR endianness settings does not match target settings");
709 LOG_DEBUG("DCR 0x%" PRIx32
" numinst %i numdata %i", dcr
, mips32
->num_inst_bpoints
,
710 mips32
->num_data_bpoints
);
712 mips32
->bp_scanned
= 1;
717 int mips32_enable_interrupts(struct target
*target
, int enable
)
723 /* read debug control register */
724 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
725 if (retval
!= ERROR_OK
)
729 if (!(dcr
& EJTAG_DCR_INTE
)) {
730 /* enable interrupts */
731 dcr
|= EJTAG_DCR_INTE
;
735 if (dcr
& EJTAG_DCR_INTE
) {
736 /* disable interrupts */
737 dcr
&= ~EJTAG_DCR_INTE
;
743 retval
= target_write_u32(target
, EJTAG_DCR
, dcr
);
744 if (retval
!= ERROR_OK
)
751 /* read processor identification cp0 register */
752 static int mips32_read_c0_prid(struct target
*target
)
754 struct mips32_common
*mips32
= target_to_mips32(target
);
755 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
758 retval
= mips32_cp0_read(ejtag_info
, &mips32
->prid
, 15, 0);
759 if (retval
!= ERROR_OK
) {
760 LOG_ERROR("processor id not available, failed to read cp0 PRId register");
768 * Detect processor type and apply required quirks.
770 * NOTE: The proper detection of certain CPUs can become quite complicated.
771 * Please consult the following Linux kernel code when adding new CPUs:
772 * arch/mips/include/asm/cpu.h
773 * arch/mips/kernel/cpu-probe.c
775 int mips32_cpu_probe(struct target
*target
)
777 struct mips32_common
*mips32
= target_to_mips32(target
);
778 const char *cpu_name
= "unknown";
782 return ERROR_OK
; /* Already probed once, return early. */
784 retval
= mips32_read_c0_prid(target
);
785 if (retval
!= ERROR_OK
)
788 switch (mips32
->prid
& PRID_COMP_MASK
) {
789 case PRID_COMP_INGENIC_E1
:
790 switch (mips32
->prid
& PRID_IMP_MASK
) {
791 case PRID_IMP_XBURST_REV1
:
792 cpu_name
= "Ingenic XBurst rev1";
793 mips32
->cpu_quirks
|= EJTAG_QUIRK_PAD_DRET
;
803 LOG_DEBUG("CPU: %s (PRId %08x)", cpu_name
, mips32
->prid
);
808 /* reads dsp implementation info from CP0 Config3 register {DSPP, DSPREV}*/
809 void mips32_read_config_dsp(struct mips32_common
*mips32
, struct mips_ejtag
*ejtag_info
)
811 uint32_t dsp_present
= ((ejtag_info
->config
[3] & MIPS32_CONFIG3_DSPP_MASK
) >> MIPS32_CONFIG3_DSPP_SHIFT
);
813 mips32
->dsp_imp
= ((ejtag_info
->config
[3] & MIPS32_CONFIG3_DSPREV_MASK
) >> MIPS32_CONFIG3_DSPREV_SHIFT
) + 1;
814 LOG_USER("DSP implemented: %s, rev %d", "yes", mips32
->dsp_imp
);
816 LOG_USER("DSP implemented: %s", "no");
820 /* read fpu implementation info from CP0 Config1 register {CU1, FP}*/
821 int mips32_read_config_fpu(struct mips32_common
*mips32
, struct mips_ejtag
*ejtag_info
)
824 uint32_t fp_imp
= (ejtag_info
->config
[1] & MIPS32_CONFIG1_FP_MASK
) >> MIPS32_CONFIG1_FP_SHIFT
;
827 LOG_USER("FPU implemented: %s", "no");
828 mips32
->fp_imp
= MIPS32_FP_IMP_NONE
;
831 uint32_t status_value
;
832 bool status_fr
, status_cu1
;
834 retval
= mips32_cp0_read(ejtag_info
, &status_value
, MIPS32_C0_STATUS
, 0);
835 if (retval
!= ERROR_OK
) {
836 LOG_ERROR("Failed to read cp0 status register");
840 status_fr
= (status_value
>> MIPS32_CP0_STATUS_FR_SHIFT
) & 0x1;
841 status_cu1
= (status_value
>> MIPS32_CP0_STATUS_CU1_SHIFT
) & 0x1;
843 /* TODO: read fpu(cp1) config register for current operating mode.
844 * Now its set to 32 bits by default. */
845 snprintf(buf
, sizeof(buf
), "yes");
846 fp_imp
= MIPS32_FP_IMP_32
;
848 snprintf(buf
, sizeof(buf
), "yes, disabled");
849 fp_imp
= MIPS32_FP_IMP_UNKNOWN
;
852 mips32
->fpu_in_64bit
= status_fr
;
853 mips32
->fpu_enabled
= status_cu1
;
855 LOG_USER("FPU implemented: %s", buf
);
856 mips32
->fp_imp
= fp_imp
;
861 /* Checks if current target implements Common Device Memory Map and therefore Fast Debug Channel (MD00090) */
862 void mips32_read_config_fdc(struct mips32_common
*mips32
, struct mips_ejtag
*ejtag_info
, uint32_t dcr
)
864 if (((ejtag_info
->config
[3] & MIPS32_CONFIG3_CDMM_MASK
) != 0) && ((dcr
& EJTAG_DCR_FDC
) != 0)) {
866 mips32
->semihosting
= 1;
869 mips32
->semihosting
= 0;
873 /* read config to config3 cp0 registers and log isa implementation */
874 int mips32_read_config_regs(struct target
*target
)
876 struct mips32_common
*mips32
= target_to_mips32(target
);
877 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
881 if (ejtag_info
->config_regs
== 0)
882 for (int i
= 0; i
!= 4; i
++) {
883 retval
= mips32_cp0_read(ejtag_info
, &ejtag_info
->config
[i
], 16, i
);
884 if (retval
!= ERROR_OK
) {
885 LOG_ERROR("isa info not available, failed to read cp0 config register: %" PRId32
, i
);
886 ejtag_info
->config_regs
= 0;
889 ejtag_info
->config_regs
= i
+ 1;
890 if ((ejtag_info
->config
[i
] & (1 << 31)) == 0)
891 break; /* no more config registers implemented */
894 return ERROR_OK
; /* already successfully read */
896 LOG_DEBUG("read %"PRIu32
" config registers", ejtag_info
->config_regs
);
898 mips32
->isa_rel
= (ejtag_info
->config
[0] & MIPS32_CONFIG0_AR_MASK
) >> MIPS32_CONFIG0_AR_SHIFT
;
899 snprintf(buf
, sizeof(buf
), ", release %s(AR=%d)",
900 mips32
->isa_rel
== MIPS32_RELEASE_1
? "1"
901 : mips32
->isa_rel
== MIPS32_RELEASE_2
? "2"
902 : mips32
->isa_rel
== MIPS32_RELEASE_6
? "6"
903 : "unknown", mips32
->isa_rel
);
905 if (ejtag_info
->impcode
& EJTAG_IMP_MIPS16
) {
906 mips32
->isa_imp
= MIPS32_MIPS16
;
907 LOG_USER("ISA implemented: %s%s", "MIPS32, MIPS16", buf
);
908 } else if (ejtag_info
->config_regs
>= 4) { /* config3 implemented */
909 unsigned isa_imp
= (ejtag_info
->config
[3] & MIPS32_CONFIG3_ISA_MASK
) >> MIPS32_CONFIG3_ISA_SHIFT
;
911 mips32
->isa_imp
= MMIPS32_ONLY
;
912 LOG_USER("ISA implemented: %s%s", "microMIPS32", buf
);
914 } else if (isa_imp
!= 0) {
915 mips32
->isa_imp
= MIPS32_MMIPS32
;
916 LOG_USER("ISA implemented: %s%s", "MIPS32, microMIPS32", buf
);
918 } else if (mips32
->isa_imp
== MIPS32_ONLY
) {
919 /* initial default value */
920 LOG_USER("ISA implemented: %s%s", "MIPS32", buf
);
923 /* Retrieve DSP info */
924 mips32_read_config_dsp(mips32
, ejtag_info
);
926 /* Retrieve if Float Point CoProcessor Implemented */
927 retval
= mips32_read_config_fpu(mips32
, ejtag_info
);
928 if (retval
!= ERROR_OK
) {
929 LOG_ERROR("fpu info is not available, error while reading cp0 status");
930 mips32
->fp_imp
= MIPS32_FP_IMP_NONE
;
936 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
937 if (retval
!= ERROR_OK
) {
938 LOG_ERROR("failed to read EJTAG_DCR register");
942 /* Determine if FDC and CDMM are implemented for this core */
943 mips32_read_config_fdc(mips32
, ejtag_info
, dcr
);
948 int mips32_checksum_memory(struct target
*target
, target_addr_t address
,
949 uint32_t count
, uint32_t *checksum
)
951 struct working_area
*crc_algorithm
;
952 struct reg_param reg_params
[2];
953 struct mips32_algorithm mips32_info
;
955 struct mips32_common
*mips32
= target_to_mips32(target
);
956 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
958 /* see contrib/loaders/checksum/mips32.s for src */
959 uint32_t isa
= ejtag_info
->isa
? 1 : 0;
961 uint32_t mips_crc_code
[] = {
962 MIPS32_ADDIU(isa
, 12, 4, 0), /* addiu $t4, $a0, 0 */
963 MIPS32_ADDIU(isa
, 10, 5, 0), /* addiu $t2, $a1, 0 */
964 MIPS32_ADDIU(isa
, 4, 0, 0xFFFF), /* addiu $a0, $zero, 0xffff */
965 MIPS32_BEQ(isa
, 0, 0, 0x10 << isa
), /* beq $zero, $zero, ncomp */
966 MIPS32_ADDIU(isa
, 11, 0, 0), /* addiu $t3, $zero, 0 */
968 MIPS32_LB(isa
, 5, 0, 12), /* lb $a1, ($t4) */
969 MIPS32_ADDI(isa
, 12, 12, 1), /* addi $t4, $t4, 1 */
970 MIPS32_SLL(isa
, 5, 5, 24), /* sll $a1, $a1, 24 */
971 MIPS32_LUI(isa
, 2, 0x04c1), /* lui $v0, 0x04c1 */
972 MIPS32_XOR(isa
, 4, 4, 5), /* xor $a0, $a0, $a1 */
973 MIPS32_ORI(isa
, 7, 2, 0x1db7), /* ori $a3, $v0, 0x1db7 */
974 MIPS32_ADDU(isa
, 6, 0, 0), /* addu $a2, $zero, $zero */
976 MIPS32_SLL(isa
, 8, 4, 1), /* sll $t0, $a0, 1 */
977 MIPS32_ADDIU(isa
, 6, 6, 1), /* addiu $a2, $a2, 1 */
978 MIPS32_SLTI(isa
, 4, 4, 0), /* slti $a0, $a0, 0 */
979 MIPS32_XOR(isa
, 9, 8, 7), /* xor $t1, $t0, $a3 */
980 MIPS32_MOVN(isa
, 8, 9, 4), /* movn $t0, $t1, $a0 */
981 MIPS32_SLTI(isa
, 3, 6, 8), /* slti $v1, $a2, 8 */
982 MIPS32_BNE(isa
, 3, 0, NEG16(7 << isa
)), /* bne $v1, $zero, loop */
983 MIPS32_ADDU(isa
, 4, 8, 0), /* addu $a0, $t0, $zero */
985 MIPS32_BNE(isa
, 10, 11, NEG16(16 << isa
)), /* bne $t2, $t3, nbyte */
986 MIPS32_ADDIU(isa
, 11, 11, 1), /* addiu $t3, $t3, 1 */
990 /* make sure we have a working area */
991 if (target_alloc_working_area(target
, sizeof(mips_crc_code
), &crc_algorithm
) != ERROR_OK
)
992 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
994 pracc_swap16_array(ejtag_info
, mips_crc_code
, ARRAY_SIZE(mips_crc_code
));
996 /* convert mips crc code into a buffer in target endianness */
997 uint8_t mips_crc_code_8
[sizeof(mips_crc_code
)];
998 target_buffer_set_u32_array(target
, mips_crc_code_8
,
999 ARRAY_SIZE(mips_crc_code
), mips_crc_code
);
1001 int retval
= target_write_buffer(target
, crc_algorithm
->address
, sizeof(mips_crc_code
), mips_crc_code_8
);
1002 if (retval
!= ERROR_OK
)
1005 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
1006 mips32_info
.isa_mode
= isa
? MIPS32_ISA_MMIPS32
: MIPS32_ISA_MIPS32
; /* run isa as in debug mode */
1008 init_reg_param(®_params
[0], "r4", 32, PARAM_IN_OUT
);
1009 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
1011 init_reg_param(®_params
[1], "r5", 32, PARAM_OUT
);
1012 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
1014 unsigned int timeout
= 20000 * (1 + (count
/ (1024 * 1024)));
1016 retval
= target_run_algorithm(target
, 0, NULL
, 2, reg_params
, crc_algorithm
->address
,
1017 crc_algorithm
->address
+ (sizeof(mips_crc_code
) - 4), timeout
, &mips32_info
);
1019 if (retval
== ERROR_OK
)
1020 *checksum
= buf_get_u32(reg_params
[0].value
, 0, 32);
1022 destroy_reg_param(®_params
[0]);
1023 destroy_reg_param(®_params
[1]);
1025 target_free_working_area(target
, crc_algorithm
);
1030 /** Checks whether a memory region is erased. */
1031 int mips32_blank_check_memory(struct target
*target
,
1032 struct target_memory_check_block
*blocks
, int num_blocks
,
1033 uint8_t erased_value
)
1035 struct working_area
*erase_check_algorithm
;
1036 struct reg_param reg_params
[3];
1037 struct mips32_algorithm mips32_info
;
1039 struct mips32_common
*mips32
= target_to_mips32(target
);
1040 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
1042 if (erased_value
!= 0xff) {
1043 LOG_ERROR("Erase value 0x%02" PRIx8
" not yet supported for MIPS32",
1047 uint32_t isa
= ejtag_info
->isa
? 1 : 0;
1048 uint32_t erase_check_code
[] = {
1050 MIPS32_LB(isa
, 8, 0, 4), /* lb $t0, ($a0) */
1051 MIPS32_AND(isa
, 6, 6, 8), /* and $a2, $a2, $t0 */
1052 MIPS32_ADDIU(isa
, 5, 5, NEG16(1)), /* addiu $a1, $a1, -1 */
1053 MIPS32_BNE(isa
, 5, 0, NEG16(4 << isa
)), /* bne $a1, $zero, nbyte */
1054 MIPS32_ADDIU(isa
, 4, 4, 1), /* addiu $a0, $a0, 1 */
1055 MIPS32_SDBBP(isa
) /* sdbbp */
1058 /* make sure we have a working area */
1059 if (target_alloc_working_area(target
, sizeof(erase_check_code
), &erase_check_algorithm
) != ERROR_OK
)
1060 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1062 pracc_swap16_array(ejtag_info
, erase_check_code
, ARRAY_SIZE(erase_check_code
));
1064 /* convert erase check code into a buffer in target endianness */
1065 uint8_t erase_check_code_8
[sizeof(erase_check_code
)];
1066 target_buffer_set_u32_array(target
, erase_check_code_8
,
1067 ARRAY_SIZE(erase_check_code
), erase_check_code
);
1069 int retval
= target_write_buffer(target
, erase_check_algorithm
->address
,
1070 sizeof(erase_check_code
), erase_check_code_8
);
1071 if (retval
!= ERROR_OK
)
1074 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
1075 mips32_info
.isa_mode
= isa
? MIPS32_ISA_MMIPS32
: MIPS32_ISA_MIPS32
;
1077 init_reg_param(®_params
[0], "r4", 32, PARAM_OUT
);
1078 buf_set_u32(reg_params
[0].value
, 0, 32, blocks
[0].address
);
1080 init_reg_param(®_params
[1], "r5", 32, PARAM_OUT
);
1081 buf_set_u32(reg_params
[1].value
, 0, 32, blocks
[0].size
);
1083 init_reg_param(®_params
[2], "r6", 32, PARAM_IN_OUT
);
1084 buf_set_u32(reg_params
[2].value
, 0, 32, erased_value
);
1086 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
, erase_check_algorithm
->address
,
1087 erase_check_algorithm
->address
+ (sizeof(erase_check_code
) - 4), 10000, &mips32_info
);
1089 if (retval
== ERROR_OK
)
1090 blocks
[0].result
= buf_get_u32(reg_params
[2].value
, 0, 32);
1092 destroy_reg_param(®_params
[0]);
1093 destroy_reg_param(®_params
[1]);
1094 destroy_reg_param(®_params
[2]);
1097 target_free_working_area(target
, erase_check_algorithm
);
1099 if (retval
!= ERROR_OK
)
1102 return 1; /* only one block has been checked */
1105 static int mips32_verify_pointer(struct command_invocation
*cmd
,
1106 struct mips32_common
*mips32
)
1108 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
1109 command_print(cmd
, "target is not an MIPS32");
1110 return ERROR_TARGET_INVALID
;
1116 * MIPS32 targets expose command interface
1117 * to manipulate CP0 registers
1119 COMMAND_HANDLER(mips32_handle_cp0_command
)
1122 struct target
*target
= get_current_target(CMD_CTX
);
1123 struct mips32_common
*mips32
= target_to_mips32(target
);
1124 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
1127 retval
= mips32_verify_pointer(CMD
, mips32
);
1128 if (retval
!= ERROR_OK
)
1131 if (target
->state
!= TARGET_HALTED
) {
1132 command_print(CMD
, "Error: target must be stopped for \"%s\" command", CMD_NAME
);
1133 return ERROR_TARGET_NOT_HALTED
;
1136 /* two or more argument, access a single register/select (write if third argument is given) */
1138 return ERROR_COMMAND_SYNTAX_ERROR
;
1140 uint32_t cp0_reg
, cp0_sel
;
1141 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], cp0_reg
);
1142 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], cp0_sel
);
1144 if (CMD_ARGC
== 2) {
1147 retval
= mips32_cp0_read(ejtag_info
, &value
, cp0_reg
, cp0_sel
);
1148 if (retval
!= ERROR_OK
) {
1150 "couldn't access reg %" PRIu32
,
1154 command_print(CMD
, "cp0 reg %" PRIu32
", select %" PRIu32
": %8.8" PRIx32
,
1155 cp0_reg
, cp0_sel
, value
);
1157 } else if (CMD_ARGC
== 3) {
1159 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], value
);
1160 retval
= mips32_cp0_write(ejtag_info
, value
, cp0_reg
, cp0_sel
);
1161 if (retval
!= ERROR_OK
) {
1163 "couldn't access cp0 reg %" PRIu32
", select %" PRIu32
,
1167 command_print(CMD
, "cp0 reg %" PRIu32
", select %" PRIu32
": %8.8" PRIx32
,
1168 cp0_reg
, cp0_sel
, value
);
1175 COMMAND_HANDLER(mips32_handle_scan_delay_command
)
1177 struct target
*target
= get_current_target(CMD_CTX
);
1178 struct mips32_common
*mips32
= target_to_mips32(target
);
1179 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
1182 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], ejtag_info
->scan_delay
);
1183 else if (CMD_ARGC
> 1)
1184 return ERROR_COMMAND_SYNTAX_ERROR
;
1186 command_print(CMD
, "scan delay: %d nsec", ejtag_info
->scan_delay
);
1187 if (ejtag_info
->scan_delay
>= MIPS32_SCAN_DELAY_LEGACY_MODE
) {
1188 ejtag_info
->mode
= 0;
1189 command_print(CMD
, "running in legacy mode");
1191 ejtag_info
->mode
= 1;
1192 command_print(CMD
, "running in fast queued mode");
1198 static const struct command_registration mips32_exec_command_handlers
[] = {
1201 .handler
= mips32_handle_cp0_command
,
1202 .mode
= COMMAND_EXEC
,
1203 .usage
= "regnum select [value]",
1204 .help
= "display/modify cp0 register",
1207 .name
= "scan_delay",
1208 .handler
= mips32_handle_scan_delay_command
,
1209 .mode
= COMMAND_ANY
,
1210 .help
= "display/set scan delay in nano seconds",
1213 COMMAND_REGISTRATION_DONE
1216 const struct command_registration mips32_command_handlers
[] = {
1219 .mode
= COMMAND_ANY
,
1220 .help
= "mips32 command group",
1222 .chain
= mips32_exec_command_handlers
,
1224 COMMAND_REGISTRATION_DONE
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)