]> git.sur5r.net Git - openocd/blob - src/target/mips32.c
duan ellis target tcl work in progress
[openocd] / 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, 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 }