2 * Support for processors implementing MIPS64 instruction set
4 * Copyright (C) 2014 by Andrey Sidorov <anysidorov@gmail.com>
5 * Copyright (C) 2014 by Aleksey Kuleshov <rndfax@yandex.ru>
6 * Copyright (C) 2014 by Antony Pavlov <antonynpavlov@gmail.com>
7 * Copyright (C) 2014 by Peter Mamonov <pmamonov@gmail.com>
9 * Based on the work of:
10 * Copyright (C) 2008 by Spencer Oliver
11 * Copyright (C) 2008 by David T.L. Wong
12 * Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev
14 * SPDX-License-Identifier: GPL-2.0-or-later
21 #if BUILD_TARGET64 == 1
33 { 0, "r0", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
34 { 1, "r1", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
35 { 2, "r2", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
36 { 3, "r3", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
37 { 4, "r4", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
38 { 5, "r5", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
39 { 6, "r6", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
40 { 7, "r7", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
41 { 8, "r8", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
42 { 9, "r9", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
43 { 10, "r10", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
44 { 11, "r11", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
45 { 12, "r12", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
46 { 13, "r13", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
47 { 14, "r14", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
48 { 15, "r15", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
49 { 16, "r16", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
50 { 17, "r17", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
51 { 18, "r18", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
52 { 19, "r19", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
53 { 20, "r20", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
54 { 21, "r21", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
55 { 22, "r22", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
56 { 23, "r23", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
57 { 24, "r24", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
58 { 25, "r25", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
59 { 26, "r26", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
60 { 27, "r27", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
61 { 28, "r28", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
62 { 29, "r29", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
63 { 30, "r30", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
64 { 31, "r31", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
65 { 32, "lo", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
66 { 33, "hi", REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.mips.cpu", 0 },
67 { MIPS64_NUM_CORE_REGS
+ 0, "pc", REG_TYPE_UINT64
, NULL
,
68 "org.gnu.gdb.mips.cpu", 0 },
69 { MIPS64_NUM_CORE_REGS
+ 1, "Random", REG_TYPE_UINT32
, NULL
,
70 "org.gnu.gdb.mips.cp0", 0 },
71 { MIPS64_NUM_CORE_REGS
+ 2, "Entrylo_0", REG_TYPE_UINT64
, NULL
,
72 "org.gnu.gdb.mips.cp0", 0 },
73 { MIPS64_NUM_CORE_REGS
+ 3, "Entrylo_1", REG_TYPE_UINT64
, NULL
,
74 "org.gnu.gdb.mips.cp0", 0 },
75 { MIPS64_NUM_CORE_REGS
+ 4, "Context", REG_TYPE_UINT64
, NULL
,
76 "org.gnu.gdb.mips.cp0", 0 },
77 { MIPS64_NUM_CORE_REGS
+ 5, "Pagemask", REG_TYPE_UINT32
, NULL
,
78 "org.gnu.gdb.mips.cp0", 0 },
79 { MIPS64_NUM_CORE_REGS
+ 6, "Wired", REG_TYPE_UINT32
, NULL
,
80 "org.gnu.gdb.mips.cp0", 0 },
81 { MIPS64_NUM_CORE_REGS
+ 7, "badvaddr", REG_TYPE_UINT64
, NULL
,
82 "org.gnu.gdb.mips.cp0", 0 },
83 { MIPS64_NUM_CORE_REGS
+ 8, "Count", REG_TYPE_UINT32
, NULL
,
84 "org.gnu.gdb.mips.cp0", 0 },
85 { MIPS64_NUM_CORE_REGS
+ 9, "EntryHi", REG_TYPE_UINT64
, NULL
,
86 "org.gnu.gdb.mips.cp0", 0 },
87 { MIPS64_NUM_CORE_REGS
+ 10, "Compare", REG_TYPE_UINT32
, NULL
,
88 "org.gnu.gdb.mips.cp0", 0 },
89 { MIPS64_NUM_CORE_REGS
+ 11, "status", REG_TYPE_UINT32
, NULL
,
90 "org.gnu.gdb.mips.cp0", 0 },
91 { MIPS64_NUM_CORE_REGS
+ 12, "cause", REG_TYPE_UINT32
, NULL
,
92 "org.gnu.gdb.mips.cp0", 0 },
93 { MIPS64_NUM_CORE_REGS
+ 13, "EPC", REG_TYPE_UINT64
, NULL
,
94 "org.gnu.gdb.mips.cp0", 0 },
95 { MIPS64_NUM_CORE_REGS
+ 14, "PrID", REG_TYPE_UINT32
, NULL
,
96 "org.gnu.gdb.mips.cp0", 0 },
97 { MIPS64_NUM_CORE_REGS
+ 15, "Config", REG_TYPE_UINT32
, NULL
,
98 "org.gnu.gdb.mips.cp0", 0 },
99 { MIPS64_NUM_CORE_REGS
+ 16, "LLA", REG_TYPE_UINT32
, NULL
,
100 "org.gnu.gdb.mips.cp0", 0 },
101 { MIPS64_NUM_CORE_REGS
+ 17, "WatchLo0", REG_TYPE_UINT64
, NULL
,
102 "org.gnu.gdb.mips.cp0", 0 },
103 { MIPS64_NUM_CORE_REGS
+ 18, "WatchLo1", REG_TYPE_UINT64
, NULL
,
104 "org.gnu.gdb.mips.cp0", 0 },
105 { MIPS64_NUM_CORE_REGS
+ 19, "WatchHi0", REG_TYPE_UINT32
, NULL
,
106 "org.gnu.gdb.mips.cp0", 0 },
107 { MIPS64_NUM_CORE_REGS
+ 20, "WatchHi1", REG_TYPE_UINT32
, NULL
,
108 "org.gnu.gdb.mips.cp0", 0 },
109 { MIPS64_NUM_CORE_REGS
+ 21, "Xcontext", REG_TYPE_UINT64
, NULL
,
110 "org.gnu.gdb.mips.cp0", 0 },
111 { MIPS64_NUM_CORE_REGS
+ 22, "ChipMemCtrl", REG_TYPE_UINT32
, NULL
,
112 "org.gnu.gdb.mips.cp0", 0 },
113 { MIPS64_NUM_CORE_REGS
+ 23, "Debug", REG_TYPE_UINT32
, NULL
,
114 "org.gnu.gdb.mips.cp0", 0 },
115 { MIPS64_NUM_CORE_REGS
+ 24, "Perfcount, sel=0", REG_TYPE_UINT32
, NULL
,
116 "org.gnu.gdb.mips.cp0", 0 },
117 { MIPS64_NUM_CORE_REGS
+ 25, "Perfcount, sel=1", REG_TYPE_UINT64
, NULL
,
118 "org.gnu.gdb.mips.cp0", 0 },
119 { MIPS64_NUM_CORE_REGS
+ 26, "Perfcount, sel=2", REG_TYPE_UINT32
, NULL
,
120 "org.gnu.gdb.mips.cp0", 0 },
121 { MIPS64_NUM_CORE_REGS
+ 27, "Perfcount, sel=3", REG_TYPE_UINT64
, NULL
,
122 "org.gnu.gdb.mips.cp0", 0 },
123 { MIPS64_NUM_CORE_REGS
+ 28, "ECC", REG_TYPE_UINT32
, NULL
,
124 "org.gnu.gdb.mips.cp0", 0 },
125 { MIPS64_NUM_CORE_REGS
+ 29, "CacheErr", REG_TYPE_UINT32
, NULL
,
126 "org.gnu.gdb.mips.cp0", 0 },
127 { MIPS64_NUM_CORE_REGS
+ 30, "TagLo", REG_TYPE_UINT32
, NULL
,
128 "org.gnu.gdb.mips.cp0", 0 },
129 { MIPS64_NUM_CORE_REGS
+ 31, "TagHi", REG_TYPE_UINT32
, NULL
,
130 "org.gnu.gdb.mips.cp0", 0 },
131 { MIPS64_NUM_CORE_REGS
+ 32, "DataHi", REG_TYPE_UINT64
, NULL
,
132 "org.gnu.gdb.mips.cp0", 0 },
133 { MIPS64_NUM_CORE_REGS
+ 33, "EEPC", REG_TYPE_UINT64
, NULL
,
134 "org.gnu.gdb.mips.cp0", 0 },
135 { MIPS64_NUM_CORE_C0_REGS
+ 0, "f0", REG_TYPE_IEEE_DOUBLE
, NULL
,
136 "org.gnu.gdb.mips.fpu", 0 },
137 { MIPS64_NUM_CORE_C0_REGS
+ 1, "f1", REG_TYPE_IEEE_DOUBLE
, NULL
,
138 "org.gnu.gdb.mips.fpu", 0 },
139 { MIPS64_NUM_CORE_C0_REGS
+ 2, "f2", REG_TYPE_IEEE_DOUBLE
, NULL
,
140 "org.gnu.gdb.mips.fpu", 0 },
141 { MIPS64_NUM_CORE_C0_REGS
+ 3, "f3", REG_TYPE_IEEE_DOUBLE
, NULL
,
142 "org.gnu.gdb.mips.fpu", 0 },
143 { MIPS64_NUM_CORE_C0_REGS
+ 4, "f4", REG_TYPE_IEEE_DOUBLE
, NULL
,
144 "org.gnu.gdb.mips.fpu", 0 },
145 { MIPS64_NUM_CORE_C0_REGS
+ 5, "f5", REG_TYPE_IEEE_DOUBLE
, NULL
,
146 "org.gnu.gdb.mips.fpu", 0 },
147 { MIPS64_NUM_CORE_C0_REGS
+ 6, "f6", REG_TYPE_IEEE_DOUBLE
, NULL
,
148 "org.gnu.gdb.mips.fpu", 0 },
149 { MIPS64_NUM_CORE_C0_REGS
+ 7, "f7", REG_TYPE_IEEE_DOUBLE
, NULL
,
150 "org.gnu.gdb.mips.fpu", 0 },
151 { MIPS64_NUM_CORE_C0_REGS
+ 8, "f8", REG_TYPE_IEEE_DOUBLE
, NULL
,
152 "org.gnu.gdb.mips.fpu", 0 },
153 { MIPS64_NUM_CORE_C0_REGS
+ 9, "f9", REG_TYPE_IEEE_DOUBLE
, NULL
,
154 "org.gnu.gdb.mips.fpu", 0 },
155 { MIPS64_NUM_CORE_C0_REGS
+ 10, "f10", REG_TYPE_IEEE_DOUBLE
, NULL
,
156 "org.gnu.gdb.mips.fpu", 0 },
157 { MIPS64_NUM_CORE_C0_REGS
+ 11, "f11", REG_TYPE_IEEE_DOUBLE
, NULL
,
158 "org.gnu.gdb.mips.fpu", 0 },
159 { MIPS64_NUM_CORE_C0_REGS
+ 12, "f12", REG_TYPE_IEEE_DOUBLE
, NULL
,
160 "org.gnu.gdb.mips.fpu", 0 },
161 { MIPS64_NUM_CORE_C0_REGS
+ 13, "f13", REG_TYPE_IEEE_DOUBLE
, NULL
,
162 "org.gnu.gdb.mips.fpu", 0 },
163 { MIPS64_NUM_CORE_C0_REGS
+ 14, "f14", REG_TYPE_IEEE_DOUBLE
, NULL
,
164 "org.gnu.gdb.mips.fpu", 0 },
165 { MIPS64_NUM_CORE_C0_REGS
+ 15, "f15", REG_TYPE_IEEE_DOUBLE
, NULL
,
166 "org.gnu.gdb.mips.fpu", 0 },
167 { MIPS64_NUM_CORE_C0_REGS
+ 16, "f16", REG_TYPE_IEEE_DOUBLE
, NULL
,
168 "org.gnu.gdb.mips.fpu", 0 },
169 { MIPS64_NUM_CORE_C0_REGS
+ 17, "f17", REG_TYPE_IEEE_DOUBLE
, NULL
,
170 "org.gnu.gdb.mips.fpu", 0 },
171 { MIPS64_NUM_CORE_C0_REGS
+ 18, "f18", REG_TYPE_IEEE_DOUBLE
, NULL
,
172 "org.gnu.gdb.mips.fpu", 0 },
173 { MIPS64_NUM_CORE_C0_REGS
+ 19, "f19", REG_TYPE_IEEE_DOUBLE
, NULL
,
174 "org.gnu.gdb.mips.fpu", 0 },
175 { MIPS64_NUM_CORE_C0_REGS
+ 20, "f20", REG_TYPE_IEEE_DOUBLE
, NULL
,
176 "org.gnu.gdb.mips.fpu", 0 },
177 { MIPS64_NUM_CORE_C0_REGS
+ 21, "f21", REG_TYPE_IEEE_DOUBLE
, NULL
,
178 "org.gnu.gdb.mips.fpu", 0 },
179 { MIPS64_NUM_CORE_C0_REGS
+ 22, "f22", REG_TYPE_IEEE_DOUBLE
, NULL
,
180 "org.gnu.gdb.mips.fpu", 0 },
181 { MIPS64_NUM_CORE_C0_REGS
+ 23, "f23", REG_TYPE_IEEE_DOUBLE
, NULL
,
182 "org.gnu.gdb.mips.fpu", 0 },
183 { MIPS64_NUM_CORE_C0_REGS
+ 24, "f24", REG_TYPE_IEEE_DOUBLE
, NULL
,
184 "org.gnu.gdb.mips.fpu", 0 },
185 { MIPS64_NUM_CORE_C0_REGS
+ 25, "f25", REG_TYPE_IEEE_DOUBLE
, NULL
,
186 "org.gnu.gdb.mips.fpu", 0 },
187 { MIPS64_NUM_CORE_C0_REGS
+ 26, "f26", REG_TYPE_IEEE_DOUBLE
, NULL
,
188 "org.gnu.gdb.mips.fpu", 0 },
189 { MIPS64_NUM_CORE_C0_REGS
+ 27, "f27", REG_TYPE_IEEE_DOUBLE
, NULL
,
190 "org.gnu.gdb.mips.fpu", 0 },
191 { MIPS64_NUM_CORE_C0_REGS
+ 28, "f28", REG_TYPE_IEEE_DOUBLE
, NULL
,
192 "org.gnu.gdb.mips.fpu", 0 },
193 { MIPS64_NUM_CORE_C0_REGS
+ 29, "f29", REG_TYPE_IEEE_DOUBLE
, NULL
,
194 "org.gnu.gdb.mips.fpu", 0 },
195 { MIPS64_NUM_CORE_C0_REGS
+ 30, "f30", REG_TYPE_IEEE_DOUBLE
, NULL
,
196 "org.gnu.gdb.mips.fpu", 0 },
197 { MIPS64_NUM_CORE_C0_REGS
+ 31, "f31", REG_TYPE_IEEE_DOUBLE
, NULL
,
198 "org.gnu.gdb.mips.fpu", 0 },
199 { MIPS64_NUM_CORE_C0_REGS
+ 32, "fcsr", REG_TYPE_INT
, "float",
200 "org.gnu.gdb.mips.fpu", 0 },
201 { MIPS64_NUM_CORE_C0_REGS
+ 33, "fir", REG_TYPE_INT
, "float",
202 "org.gnu.gdb.mips.fpu", 0 },
203 { MIPS64_NUM_CORE_C0_REGS
+ 34, "fconfig", REG_TYPE_INT
, "float",
204 "org.gnu.gdb.mips.fpu", 0 },
205 { MIPS64_NUM_CORE_C0_REGS
+ 35, "fccr", REG_TYPE_INT
, "float",
206 "org.gnu.gdb.mips.fpu", 0 },
207 { MIPS64_NUM_CORE_C0_REGS
+ 36, "fexr", REG_TYPE_INT
, "float",
208 "org.gnu.gdb.mips.fpu", 0 },
209 { MIPS64_NUM_CORE_C0_REGS
+ 37, "fenr", REG_TYPE_INT
, "float",
210 "org.gnu.gdb.mips.fpu", 0 },
213 static int reg_type2size(enum reg_type type
)
216 case REG_TYPE_UINT32
:
219 case REG_TYPE_UINT64
:
220 case REG_TYPE_IEEE_DOUBLE
:
227 static int mips64_get_core_reg(struct reg
*reg
)
230 struct mips64_core_reg
*mips64_reg
= reg
->arch_info
;
231 struct target
*target
= mips64_reg
->target
;
232 struct mips64_common
*mips64_target
= target
->arch_info
;
234 if (target
->state
!= TARGET_HALTED
)
235 return ERROR_TARGET_NOT_HALTED
;
237 retval
= mips64_target
->read_core_reg(target
, mips64_reg
->num
);
242 static int mips64_set_core_reg(struct reg
*reg
, uint8_t *buf
)
244 struct mips64_core_reg
*mips64_reg
= reg
->arch_info
;
245 struct target
*target
= mips64_reg
->target
;
246 uint64_t value
= buf_get_u64(buf
, 0, 64);
248 if (target
->state
!= TARGET_HALTED
)
249 return ERROR_TARGET_NOT_HALTED
;
251 buf_set_u64(reg
->value
, 0, 64, value
);
258 static int mips64_read_core_reg(struct target
*target
, int num
)
262 /* get pointers to arch-specific information */
263 struct mips64_common
*mips64
= target
->arch_info
;
265 if ((num
< 0) || (num
>= MIPS64_NUM_REGS
))
266 return ERROR_COMMAND_ARGUMENT_INVALID
;
268 reg_value
= mips64
->core_regs
[num
];
269 buf_set_u64(mips64
->core_cache
->reg_list
[num
].value
, 0, 64, reg_value
);
270 mips64
->core_cache
->reg_list
[num
].valid
= 1;
271 mips64
->core_cache
->reg_list
[num
].dirty
= 0;
276 static int mips64_write_core_reg(struct target
*target
, int num
)
280 /* get pointers to arch-specific information */
281 struct mips64_common
*mips64
= target
->arch_info
;
283 if ((num
< 0) || (num
>= MIPS64_NUM_REGS
))
284 return ERROR_COMMAND_ARGUMENT_INVALID
;
286 reg_value
= buf_get_u64(mips64
->core_cache
->reg_list
[num
].value
, 0, 64);
287 mips64
->core_regs
[num
] = reg_value
;
288 LOG_DEBUG("write core reg %i value 0x%" PRIx64
"", num
, reg_value
);
289 mips64
->core_cache
->reg_list
[num
].valid
= 1;
290 mips64
->core_cache
->reg_list
[num
].dirty
= 0;
295 int mips64_invalidate_core_regs(struct target
*target
)
297 /* get pointers to arch-specific information */
298 struct mips64_common
*mips64
= target
->arch_info
;
301 for (i
= 0; i
< mips64
->core_cache
->num_regs
; i
++) {
302 mips64
->core_cache
->reg_list
[i
].valid
= 0;
303 mips64
->core_cache
->reg_list
[i
].dirty
= 0;
310 int mips64_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
311 int *reg_list_size
, enum target_register_class reg_class
)
313 /* get pointers to arch-specific information */
314 struct mips64_common
*mips64
= target
->arch_info
;
317 /* include floating point registers */
318 *reg_list_size
= MIPS64_NUM_REGS
;
319 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
321 for (i
= 0; i
< MIPS64_NUM_REGS
; i
++)
322 (*reg_list
)[i
] = &mips64
->core_cache
->reg_list
[i
];
327 int mips64_save_context(struct target
*target
)
330 struct mips64_common
*mips64
= target
->arch_info
;
331 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
333 retval
= mips64_pracc_read_regs(ejtag_info
, mips64
->core_regs
);
334 if (retval
!= ERROR_OK
)
337 for (unsigned i
= 0; i
< MIPS64_NUM_REGS
; i
++)
338 retval
= mips64
->read_core_reg(target
, i
);
343 int mips64_restore_context(struct target
*target
)
345 struct mips64_common
*mips64
= target
->arch_info
;
346 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
348 for (unsigned i
= 0; i
< MIPS64_NUM_REGS
; i
++) {
349 if (mips64
->core_cache
->reg_list
[i
].dirty
)
350 mips64
->write_core_reg(target
, i
);
353 return mips64_pracc_write_regs(ejtag_info
, mips64
->core_regs
);
356 int mips64_arch_state(struct target
*target
)
358 struct mips64_common
*mips64
= target
->arch_info
;
359 struct reg
*pc
= &mips64
->core_cache
->reg_list
[MIPS64_PC
];
361 if (mips64
->common_magic
!= MIPS64_COMMON_MAGIC
) {
362 LOG_ERROR("BUG: called for a non-MIPS64 target");
366 LOG_USER("target halted due to %s, pc: 0x%" PRIx64
"",
367 debug_reason_name(target
), buf_get_u64(pc
->value
, 0, 64));
372 static const struct reg_arch_type mips64_reg_type
= {
373 .get
= mips64_get_core_reg
,
374 .set
= mips64_set_core_reg
,
377 int mips64_build_reg_cache(struct target
*target
)
379 /* get pointers to arch-specific information */
380 struct mips64_common
*mips64
= target
->arch_info
;
381 struct reg_cache
**cache_p
, *cache
;
382 struct mips64_core_reg
*arch_info
= NULL
;
383 struct reg
*reg_list
= NULL
;
386 cache
= calloc(1, sizeof(*cache
));
388 LOG_ERROR("unable to allocate cache");
392 reg_list
= calloc(MIPS64_NUM_REGS
, sizeof(*reg_list
));
394 LOG_ERROR("unable to allocate reg_list");
398 arch_info
= calloc(MIPS64_NUM_REGS
, sizeof(*arch_info
));
400 LOG_ERROR("unable to allocate arch_info");
404 for (i
= 0; i
< MIPS64_NUM_REGS
; i
++) {
405 struct mips64_core_reg
*a
= &arch_info
[i
];
406 struct reg
*r
= ®_list
[i
];
408 r
->arch_info
= &arch_info
[i
];
409 r
->caller_save
= true; /* gdb defaults to true */
411 r
->feature
= &a
->feature
;
412 r
->feature
->name
= mips64_regs
[i
].feature
;
413 r
->group
= mips64_regs
[i
].group
;
414 r
->name
= mips64_regs
[i
].name
;
416 r
->reg_data_type
= &a
->reg_data_type
;
417 r
->reg_data_type
->type
= mips64_regs
[i
].type
;
418 r
->size
= reg_type2size(mips64_regs
[i
].type
);
419 r
->type
= &mips64_reg_type
;
420 r
->value
= &a
->value
[0];
422 a
->mips64_common
= mips64
;
423 a
->num
= mips64_regs
[i
].id
;
427 cache
->name
= "mips64 registers";
428 cache
->reg_list
= reg_list
;
429 cache
->num_regs
= MIPS64_NUM_REGS
;
431 cache_p
= register_get_last_cache_p(&target
->reg_cache
);
434 mips64
->core_cache
= cache
;
446 int mips64_init_arch_info(struct target
*target
, struct mips64_common
*mips64
,
447 struct jtag_tap
*tap
)
449 mips64
->bp_scanned
= false;
450 mips64
->common_magic
= MIPS64_COMMON_MAGIC
;
451 mips64
->data_break_list
= NULL
;
452 mips64
->ejtag_info
.tap
= tap
;
453 mips64
->fast_data_area
= NULL
;
454 mips64
->mips64mode32
= false;
455 mips64
->read_core_reg
= mips64_read_core_reg
;
456 mips64
->write_core_reg
= mips64_write_core_reg
;
461 int mips64_run_algorithm(struct target
*target
, int num_mem_params
,
462 struct mem_param
*mem_params
, int num_reg_params
,
463 struct reg_param
*reg_params
, target_addr_t entry_point
,
464 target_addr_t exit_point
, int timeout_ms
, void *arch_info
)
470 int mips64_examine(struct target
*target
)
472 struct mips64_common
*mips64
= target
->arch_info
;
474 if (target_was_examined(target
))
477 /* TODO: why we do not do mips64_configure_break_unit() here? */
478 mips64
->bp_scanned
= false;
479 mips64
->num_data_bpoints
= 0;
480 mips64
->num_data_bpoints_avail
= 0;
481 mips64
->num_inst_bpoints
= 0;
482 mips64
->num_inst_bpoints_avail
= 0;
484 target_set_examined(target
);
489 static int mips64_configure_i_break_unit(struct target
*target
)
491 /* get pointers to arch-specific information */
492 struct mips64_common
*mips64
= target
->arch_info
;
493 struct mips64_comparator
*ibl
;
498 /* get number of inst breakpoints */
499 retval
= target_read_u64(target
, EJTAG64_V25_IBS
, &bpinfo
);
500 if (retval
!= ERROR_OK
)
503 mips64
->num_inst_bpoints
= (bpinfo
>> 24) & 0x0F;
504 mips64
->num_inst_bpoints_avail
= mips64
->num_inst_bpoints
;
505 ibl
= calloc(mips64
->num_inst_bpoints
, sizeof(*ibl
));
507 LOG_ERROR("unable to allocate inst_break_list");
511 for (i
= 0; i
< mips64
->num_inst_bpoints
; i
++)
512 ibl
[i
].reg_address
= EJTAG64_V25_IBA0
+ (0x100 * i
);
514 mips64
->inst_break_list
= ibl
;
516 retval
= target_write_u64(target
, EJTAG64_V25_IBS
, 0);
517 if (retval
!= ERROR_OK
)
523 static int mips64_configure_d_break_unit(struct target
*target
)
525 struct mips64_common
*mips64
= target
->arch_info
;
526 struct mips64_comparator
*dbl
;
531 /* get number of data breakpoints */
532 retval
= target_read_u64(target
, EJTAG64_V25_DBS
, &bpinfo
);
533 if (retval
!= ERROR_OK
)
536 mips64
->num_data_bpoints
= (bpinfo
>> 24) & 0x0F;
537 mips64
->num_data_bpoints_avail
= mips64
->num_data_bpoints
;
539 dbl
= calloc(mips64
->num_data_bpoints
, sizeof(*dbl
));
542 LOG_ERROR("unable to allocate data_break_list");
546 for (i
= 0; i
< mips64
->num_data_bpoints
; i
++)
547 dbl
[i
].reg_address
= EJTAG64_V25_DBA0
+ (0x100 * i
);
549 mips64
->data_break_list
= dbl
;
552 retval
= target_write_u64(target
, EJTAG64_V25_DBS
, 0);
553 if (retval
!= ERROR_OK
)
559 int mips64_configure_break_unit(struct target
*target
)
561 struct mips64_common
*mips64
= target
->arch_info
;
565 if (mips64
->bp_scanned
)
568 /* get info about breakpoint support */
569 retval
= target_read_u64(target
, EJTAG64_DCR
, &dcr
);
570 if (retval
!= ERROR_OK
)
573 if (dcr
& EJTAG64_DCR_IB
) {
574 retval
= mips64_configure_i_break_unit(target
);
575 if (retval
!= ERROR_OK
)
579 if (dcr
& EJTAG64_DCR_DB
) {
580 retval
= mips64_configure_d_break_unit(target
);
581 if (retval
!= ERROR_OK
)
585 LOG_DEBUG("DCR 0x%" PRIx64
" numinst %i numdata %i", dcr
,
586 mips64
->num_inst_bpoints
, mips64
->num_data_bpoints
);
588 mips64
->bp_scanned
= true;
593 int mips64_enable_interrupts(struct target
*target
, bool enable
)
599 /* read debug control register */
600 retval
= target_read_u64(target
, EJTAG64_DCR
, &dcr
);
601 if (retval
!= ERROR_OK
)
605 if (!(dcr
& EJTAG64_DCR_INTE
)) {
606 /* enable interrupts */
607 dcr
|= EJTAG64_DCR_INTE
;
611 if (dcr
& EJTAG64_DCR_INTE
) {
612 /* disable interrupts */
613 dcr
&= ~(uint64_t)EJTAG64_DCR_INTE
;
619 retval
= target_write_u64(target
, EJTAG64_DCR
, dcr
);
620 if (retval
!= ERROR_OK
)
627 #endif /* BUILD_TARGET64 */
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)