Duane Ellis: "target as an [tcl] object" feature.
[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 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "mips32.h"
27 #include "jtag.h"
28 #include "log.h"
29
30 #include <stdlib.h>
31 #include <string.h>
32
33 char* mips32_core_reg_list[] =
34 {
35 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
36 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
37 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
38 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
39 "status", "lo", "hi", "badvaddr", "cause", "pc"
40 };
41
42 mips32_core_reg_t mips32_core_reg_list_arch_info[MIPS32NUMCOREREGS] =
43 {
44 {0, NULL, NULL},
45 {1, NULL, NULL},
46 {2, NULL, NULL},
47 {3, NULL, NULL},
48 {4, NULL, NULL},
49 {5, NULL, NULL},
50 {6, NULL, NULL},
51 {7, NULL, NULL},
52 {8, NULL, NULL},
53 {9, NULL, NULL},
54 {10, NULL, NULL},
55 {11, NULL, NULL},
56 {12, NULL, NULL},
57 {13, NULL, NULL},
58 {14, NULL, NULL},
59 {15, NULL, NULL},
60 {16, NULL, NULL},
61 {17, NULL, NULL},
62 {18, NULL, NULL},
63 {19, NULL, NULL},
64 {20, NULL, NULL},
65 {21, NULL, NULL},
66 {22, NULL, NULL},
67 {23, NULL, NULL},
68 {24, NULL, NULL},
69 {25, NULL, NULL},
70 {26, NULL, NULL},
71 {27, NULL, NULL},
72 {28, NULL, NULL},
73 {29, NULL, NULL},
74 {30, NULL, NULL},
75 {31, NULL, NULL},
76
77 {32, NULL, NULL},
78 {33, NULL, NULL},
79 {34, NULL, NULL},
80 {35, NULL, NULL},
81 {36, NULL, NULL},
82 {37, NULL, NULL},
83 };
84
85 u8 mips32_gdb_dummy_fsr_value[] = {0, 0, 0, 0};
86
87 reg_t mips32_gdb_dummy_fsr_reg =
88 {
89 "GDB dummy floating-point status register", mips32_gdb_dummy_fsr_value, 0, 1, 32, NULL, 0, NULL, 0
90 };
91
92 u8 mips32_gdb_dummy_fir_value[] = {0, 0, 0, 0};
93
94 reg_t mips32_gdb_dummy_fir_reg =
95 {
96 "GDB dummy floating-point register", mips32_gdb_dummy_fir_value, 0, 1, 32, NULL, 0, NULL, 0
97 };
98
99 int mips32_core_reg_arch_type = -1;
100
101 int mips32_get_core_reg(reg_t *reg)
102 {
103 int retval;
104 mips32_core_reg_t *mips32_reg = reg->arch_info;
105 target_t *target = mips32_reg->target;
106 mips32_common_t *mips32_target = target->arch_info;
107
108 if (target->state != TARGET_HALTED)
109 {
110 return ERROR_TARGET_NOT_HALTED;
111 }
112
113 retval = mips32_target->read_core_reg(target, mips32_reg->num);
114
115 return retval;
116 }
117
118 int mips32_set_core_reg(reg_t *reg, u8 *buf)
119 {
120 mips32_core_reg_t *mips32_reg = reg->arch_info;
121 target_t *target = mips32_reg->target;
122 u32 value = buf_get_u32(buf, 0, 32);
123
124 if (target->state != TARGET_HALTED)
125 {
126 return ERROR_TARGET_NOT_HALTED;
127 }
128
129 buf_set_u32(reg->value, 0, 32, value);
130 reg->dirty = 1;
131 reg->valid = 1;
132
133 return ERROR_OK;
134 }
135
136 int mips32_read_core_reg(struct target_s *target, int num)
137 {
138 u32 reg_value;
139 mips32_core_reg_t *mips_core_reg;
140
141 /* get pointers to arch-specific information */
142 mips32_common_t *mips32 = target->arch_info;
143
144 if ((num < 0) || (num >= MIPS32NUMCOREREGS))
145 return ERROR_INVALID_ARGUMENTS;
146
147 mips_core_reg = mips32->core_cache->reg_list[num].arch_info;
148 reg_value = mips32->core_regs[num];
149 buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, reg_value);
150 mips32->core_cache->reg_list[num].valid = 1;
151 mips32->core_cache->reg_list[num].dirty = 0;
152
153 return ERROR_OK;
154 }
155
156 int mips32_write_core_reg(struct target_s *target, int num)
157 {
158 u32 reg_value;
159 mips32_core_reg_t *mips_core_reg;
160
161 /* get pointers to arch-specific information */
162 mips32_common_t *mips32 = target->arch_info;
163
164 if ((num < 0) || (num >= MIPS32NUMCOREREGS))
165 return ERROR_INVALID_ARGUMENTS;
166
167 reg_value = buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
168 mips_core_reg = mips32->core_cache->reg_list[num].arch_info;
169 mips32->core_regs[num] = reg_value;
170 LOG_DEBUG("write core reg %i value 0x%x", num , reg_value);
171 mips32->core_cache->reg_list[num].valid = 1;
172 mips32->core_cache->reg_list[num].dirty = 0;
173
174 return ERROR_OK;
175 }
176
177 int mips32_invalidate_core_regs(target_t *target)
178 {
179 /* get pointers to arch-specific information */
180 mips32_common_t *mips32 = target->arch_info;
181 int i;
182
183 for (i = 0; i < mips32->core_cache->num_regs; i++)
184 {
185 mips32->core_cache->reg_list[i].valid = 0;
186 mips32->core_cache->reg_list[i].dirty = 0;
187 }
188
189 return ERROR_OK;
190 }
191
192 int mips32_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list_size)
193 {
194 /* get pointers to arch-specific information */
195 mips32_common_t *mips32 = target->arch_info;
196 int i;
197
198 /* include fsr/fir reg */
199 *reg_list_size = MIPS32NUMCOREREGS + 2;
200 *reg_list = malloc(sizeof(reg_t*) * (*reg_list_size));
201
202 for (i = 0; i < MIPS32NUMCOREREGS; i++)
203 {
204 (*reg_list)[i] = &mips32->core_cache->reg_list[i];
205 }
206
207 /* add dummy floating points regs */
208 (*reg_list)[38] = &mips32_gdb_dummy_fsr_reg;
209 (*reg_list)[39] = &mips32_gdb_dummy_fir_reg;
210
211 return ERROR_OK;
212 }
213
214 int mips32_save_context(target_t *target)
215 {
216 int i;
217
218 /* get pointers to arch-specific information */
219 mips32_common_t *mips32 = target->arch_info;
220 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
221
222 /* read core registers */
223 mips32_pracc_read_regs(ejtag_info, mips32->core_regs);
224
225 for (i = 0; i < MIPS32NUMCOREREGS; i++)
226 {
227 if (!mips32->core_cache->reg_list[i].valid)
228 {
229 mips32->read_core_reg(target, i);
230 }
231 }
232
233 return ERROR_OK;
234 }
235
236 int mips32_restore_context(target_t *target)
237 {
238 int i;
239
240 /* get pointers to arch-specific information */
241 mips32_common_t *mips32 = target->arch_info;
242 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
243
244 for (i = 0; i < MIPS32NUMCOREREGS; i++)
245 {
246 if (mips32->core_cache->reg_list[i].dirty)
247 {
248 mips32->write_core_reg(target, i);
249 }
250 }
251
252 /* write core regs */
253 mips32_pracc_write_regs(ejtag_info, mips32->core_regs);
254
255 return ERROR_OK;
256 }
257
258 int mips32_arch_state(struct target_s *target)
259 {
260 mips32_common_t *mips32 = target->arch_info;
261
262 if (mips32->common_magic != MIPS32_COMMON_MAGIC)
263 {
264 LOG_ERROR("BUG: called for a non-MIPS32 target");
265 exit(-1);
266 }
267
268 LOG_USER("target halted due to %s, pc: 0x%8.8x",
269 Jim_Nvp_value2name_simple( nvp_target_debug_reason, target->debug_reason )->name ,
270 buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32));
271
272 return ERROR_OK;
273 }
274
275 reg_cache_t *mips32_build_reg_cache(target_t *target)
276 {
277 /* get pointers to arch-specific information */
278 mips32_common_t *mips32 = target->arch_info;
279
280 int num_regs = MIPS32NUMCOREREGS;
281 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
282 reg_cache_t *cache = malloc(sizeof(reg_cache_t));
283 reg_t *reg_list = malloc(sizeof(reg_t) * num_regs);
284 mips32_core_reg_t *arch_info = malloc(sizeof(mips32_core_reg_t) * num_regs);
285 int i;
286
287 if (mips32_core_reg_arch_type == -1)
288 mips32_core_reg_arch_type = register_reg_arch_type(mips32_get_core_reg, mips32_set_core_reg);
289
290 /* Build the process context cache */
291 cache->name = "mips32 registers";
292 cache->next = NULL;
293 cache->reg_list = reg_list;
294 cache->num_regs = num_regs;
295 (*cache_p) = cache;
296 mips32->core_cache = cache;
297
298 for (i = 0; i < num_regs; i++)
299 {
300 arch_info[i] = mips32_core_reg_list_arch_info[i];
301 arch_info[i].target = target;
302 arch_info[i].mips32_common = mips32;
303 reg_list[i].name = mips32_core_reg_list[i];
304 reg_list[i].size = 32;
305 reg_list[i].value = calloc(1, 4);
306 reg_list[i].dirty = 0;
307 reg_list[i].valid = 0;
308 reg_list[i].bitfield_desc = NULL;
309 reg_list[i].num_bitfields = 0;
310 reg_list[i].arch_type = mips32_core_reg_arch_type;
311 reg_list[i].arch_info = &arch_info[i];
312 }
313
314 return cache;
315 }
316
317 int mips32_init_arch_info(target_t *target, mips32_common_t *mips32, int chain_pos, const char *variant)
318 {
319 target->arch_info = mips32;
320 mips32->common_magic = MIPS32_COMMON_MAGIC;
321
322 mips32->ejtag_info.chain_pos = chain_pos;
323 mips32->read_core_reg = mips32_read_core_reg;
324 mips32->write_core_reg = mips32_write_core_reg;
325
326 return ERROR_OK;
327 }
328
329 int mips32_register_commands(struct command_context_s *cmd_ctx)
330 {
331 return ERROR_OK;
332 }
333
334 int mips32_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_params, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info)
335 {
336 /*TODO*/
337 return ERROR_OK;
338 }

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)