Holger Schurig <hs4233@mail.mn-solutions.de> fix warnings
[fw/openocd] / src / target / mips_m4k.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 "mips_m4k.h"
28 #include "mips32_dmaacc.h"
29 #include "jtag.h"
30 #include "log.h"
31
32 #include <stdlib.h>
33 #include <string.h>
34
35 /* cli handling */
36
37 /* forward declarations */
38 int mips_m4k_poll(target_t *target);
39 int mips_m4k_halt(struct target_s *target);
40 int mips_m4k_soft_reset_halt(struct target_s *target);
41 int mips_m4k_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution);
42 int mips_m4k_step(struct target_s *target, int current, u32 address, int handle_breakpoints);
43 int mips_m4k_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
44 int mips_m4k_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
45 int mips_m4k_register_commands(struct command_context_s *cmd_ctx);
46 int mips_m4k_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
47 int mips_m4k_quit(void);
48 int mips_m4k_target_create(struct target_s *target, Jim_Interp *interp);
49
50 int mips_m4k_examine(struct target_s *target);
51 int mips_m4k_assert_reset(target_t *target);
52 int mips_m4k_deassert_reset(target_t *target);
53 int mips_m4k_checksum_memory(target_t *target, u32 address, u32 size, u32 *checksum);
54
55 target_type_t mips_m4k_target =
56 {
57         .name = "mips_m4k",
58
59         .poll = mips_m4k_poll,
60         .arch_state = mips32_arch_state,
61
62         .target_request_data = NULL,
63
64         .halt = mips_m4k_halt,
65         .resume = mips_m4k_resume,
66         .step = mips_m4k_step,
67
68         .assert_reset = mips_m4k_assert_reset,
69         .deassert_reset = mips_m4k_deassert_reset,
70         .soft_reset_halt = mips_m4k_soft_reset_halt,
71
72         .get_gdb_reg_list = mips32_get_gdb_reg_list,
73
74         .read_memory = mips_m4k_read_memory,
75         .write_memory = mips_m4k_write_memory,
76         .bulk_write_memory = mips_m4k_bulk_write_memory,
77         .checksum_memory = mips_m4k_checksum_memory,
78         .blank_check_memory = NULL,
79
80         .run_algorithm = mips32_run_algorithm,
81
82         .add_breakpoint = mips_m4k_add_breakpoint,
83         .remove_breakpoint = mips_m4k_remove_breakpoint,
84         .add_watchpoint = mips_m4k_add_watchpoint,
85         .remove_watchpoint = mips_m4k_remove_watchpoint,
86
87         .register_commands = mips_m4k_register_commands,
88         .target_create = mips_m4k_target_create,
89         .init_target = mips_m4k_init_target,
90         .examine = mips_m4k_examine,
91         .quit = mips_m4k_quit
92 };
93
94 int mips_m4k_examine_debug_reason(target_t *target)
95 {
96         u32 break_status;
97         int retval;
98
99         if ((target->debug_reason != DBG_REASON_DBGRQ)
100                 && (target->debug_reason != DBG_REASON_SINGLESTEP))
101         {
102                 /* get info about inst breakpoint support */
103                 if ((retval = target_read_u32(target, EJTAG_IBS, &break_status)) != ERROR_OK)
104                         return retval;
105                 if (break_status & 0x1f)
106                 {
107                         /* we have halted on a  breakpoint */
108                         if ((retval = target_write_u32(target, EJTAG_IBS, 0)) != ERROR_OK)
109                                 return retval;
110                         target->debug_reason = DBG_REASON_BREAKPOINT;
111                 }
112
113                 /* get info about data breakpoint support */
114                 if ((retval = target_read_u32(target, 0xFF302000, &break_status)) != ERROR_OK)
115                         return retval;
116                 if (break_status & 0x1f)
117                 {
118                         /* we have halted on a  breakpoint */
119                         if ((retval = target_write_u32(target, 0xFF302000, 0)) != ERROR_OK)
120                                 return retval;
121                         target->debug_reason = DBG_REASON_WATCHPOINT;
122                 }
123         }
124
125         return ERROR_OK;
126 }
127
128 int mips_m4k_debug_entry(target_t *target)
129 {
130         mips32_common_t *mips32 = target->arch_info;
131         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
132         u32 debug_reg;
133
134         /* read debug register */
135         mips_ejtag_read_debug(ejtag_info, &debug_reg);
136
137         /* make sure break uit configured */
138         mips32_configure_break_unit(target);
139
140         /* attempt to find halt reason */
141         mips_m4k_examine_debug_reason(target);
142
143         /* clear single step if active */
144         if (debug_reg & EJTAG_DEBUG_DSS)
145         {
146                 /* stopped due to single step - clear step bit */
147                 mips_ejtag_config_step(ejtag_info, 0);
148         }
149
150         mips32_save_context(target);
151
152         LOG_DEBUG("entered debug state at PC 0x%x, target->state: %s",
153                 *(u32*)(mips32->core_cache->reg_list[MIPS32_PC].value),
154                   Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
155
156         return ERROR_OK;
157 }
158
159 int mips_m4k_poll(target_t *target)
160 {
161         int retval;
162         mips32_common_t *mips32 = target->arch_info;
163         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
164         u32 ejtag_ctrl = ejtag_info->ejtag_ctrl;
165
166         /* read ejtag control reg */
167         jtag_add_end_state(TAP_IDLE);
168         mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
169         mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
170
171         /* clear this bit before handling polling
172          * as after reset registers will read zero */
173         if (ejtag_ctrl & EJTAG_CTRL_ROCC)
174         {
175                 /* we have detected a reset, clear flag
176                  * otherwise ejtag will not work */
177                 jtag_add_end_state(TAP_IDLE);
178                 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC;
179
180                 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
181                 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
182                 LOG_DEBUG("Reset Detected");
183         }
184
185         /* check for processor halted */
186         if (ejtag_ctrl & EJTAG_CTRL_BRKST)
187         {
188                 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
189                 {
190                         jtag_add_end_state(TAP_IDLE);
191                         mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT, NULL);
192
193                         target->state = TARGET_HALTED;
194
195                         if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
196                                 return retval;
197
198                         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
199                 }
200                 else if (target->state == TARGET_DEBUG_RUNNING)
201                 {
202                         target->state = TARGET_HALTED;
203
204                         if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
205                                 return retval;
206
207                         target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
208                 }
209         }
210         else
211         {
212                 target->state = TARGET_RUNNING;
213         }
214
215 //      LOG_DEBUG("ctrl=0x%08X", ejtag_ctrl);
216
217         return ERROR_OK;
218 }
219
220 int mips_m4k_halt(struct target_s *target)
221 {
222         mips32_common_t *mips32 = target->arch_info;
223         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
224
225         LOG_DEBUG("target->state: %s",
226                   Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
227
228         if (target->state == TARGET_HALTED)
229         {
230                 LOG_DEBUG("target was already halted");
231                 return ERROR_OK;
232         }
233
234         if (target->state == TARGET_UNKNOWN)
235         {
236                 LOG_WARNING("target was in unknown state when halt was requested");
237         }
238
239         if (target->state == TARGET_RESET)
240         {
241                 if ((jtag_reset_config & RESET_SRST_PULLS_TRST) && jtag_srst)
242                 {
243                         LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
244                         return ERROR_TARGET_FAILURE;
245                 }
246                 else
247                 {
248                         /* we came here in a reset_halt or reset_init sequence
249                          * debug entry was already prepared in mips32_prepare_reset_halt()
250                          */
251                         target->debug_reason = DBG_REASON_DBGRQ;
252
253                         return ERROR_OK;
254                 }
255         }
256
257         /* break processor */
258         mips_ejtag_enter_debug(ejtag_info);
259
260         target->debug_reason = DBG_REASON_DBGRQ;
261
262         return ERROR_OK;
263 }
264
265 int mips_m4k_assert_reset(target_t *target)
266 {
267         mips32_common_t *mips32 = target->arch_info;
268         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
269
270         LOG_DEBUG("target->state: %s",
271                 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
272
273         if (!(jtag_reset_config & RESET_HAS_SRST))
274         {
275                 LOG_ERROR("Can't assert SRST");
276                 return ERROR_FAIL;
277         }
278
279         if (target->reset_halt)
280         {
281                 /* use hardware to catch reset */
282                 jtag_add_end_state(TAP_IDLE);
283                 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT, NULL);
284         }
285         else
286         {
287                 jtag_add_end_state(TAP_IDLE);
288                 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT, NULL);
289         }
290
291         if (strcmp(target->variant, "ejtag_srst") == 0)
292         {
293                 u32 ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_PRRST | EJTAG_CTRL_PERRST;
294                 LOG_DEBUG("Using EJTAG reset (PRRST) to reset processor...");
295                 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
296                 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
297         }
298         else
299         {
300                 /* here we should issue a srst only, but we may have to assert trst as well */
301                 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
302                 {
303                         jtag_add_reset(1, 1);
304                 }
305                 else
306                 {
307                         jtag_add_reset(0, 1);
308                 }
309         }
310
311         target->state = TARGET_RESET;
312         jtag_add_sleep(50000);
313
314         mips32_invalidate_core_regs(target);
315
316         if (target->reset_halt)
317         {
318                 int retval;
319                 if ((retval = target_halt(target))!=ERROR_OK)
320                         return retval;
321         }
322
323         return ERROR_OK;
324 }
325
326 int mips_m4k_deassert_reset(target_t *target)
327 {
328         LOG_DEBUG("target->state: %s",
329                 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
330
331         /* deassert reset lines */
332         jtag_add_reset(0, 0);
333
334         return ERROR_OK;
335 }
336
337 int mips_m4k_soft_reset_halt(struct target_s *target)
338 {
339         /* TODO */
340         return ERROR_OK;
341 }
342
343 int mips_m4k_single_step_core(target_t *target)
344 {
345         mips32_common_t *mips32 = target->arch_info;
346         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
347
348         /* configure single step mode */
349         mips_ejtag_config_step(ejtag_info, 1);
350
351         /* exit debug mode */
352         mips_ejtag_exit_debug(ejtag_info, 1);
353
354         mips_m4k_debug_entry(target);
355
356         return ERROR_OK;
357 }
358
359 int mips_m4k_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
360 {
361         mips32_common_t *mips32 = target->arch_info;
362         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
363         breakpoint_t *breakpoint = NULL;
364         u32 resume_pc;
365
366         if (target->state != TARGET_HALTED)
367         {
368                 LOG_WARNING("target not halted");
369                 return ERROR_TARGET_NOT_HALTED;
370         }
371
372         if (!debug_execution)
373         {
374                 target_free_all_working_areas(target);
375                 mips_m4k_enable_breakpoints(target);
376                 mips_m4k_enable_watchpoints(target);
377         }
378
379         /* current = 1: continue on current pc, otherwise continue at <address> */
380         if (!current)
381         {
382                 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
383                 mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
384                 mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
385         }
386
387         resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
388
389         mips32_restore_context(target);
390
391         /* the front-end may request us not to handle breakpoints */
392         if (handle_breakpoints)
393         {
394                 /* Single step past breakpoint at current address */
395                 if ((breakpoint = breakpoint_find(target, resume_pc)))
396                 {
397                         LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
398                         mips_m4k_unset_breakpoint(target, breakpoint);
399                         mips_m4k_single_step_core(target);
400                         mips_m4k_set_breakpoint(target, breakpoint);
401                 }
402         }
403
404         /* exit debug mode - enable interrupts if required */
405         mips_ejtag_exit_debug(ejtag_info, !debug_execution);
406         target->debug_reason = DBG_REASON_NOTHALTED;
407
408         /* registers are now invalid */
409         mips32_invalidate_core_regs(target);
410
411         if (!debug_execution)
412         {
413                 target->state = TARGET_RUNNING;
414                 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
415                 LOG_DEBUG("target resumed at 0x%x", resume_pc);
416         }
417         else
418         {
419                 target->state = TARGET_DEBUG_RUNNING;
420                 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
421                 LOG_DEBUG("target debug resumed at 0x%x", resume_pc);
422         }
423
424         return ERROR_OK;
425 }
426
427 int mips_m4k_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
428 {
429         /* get pointers to arch-specific information */
430         mips32_common_t *mips32 = target->arch_info;
431         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
432         breakpoint_t *breakpoint = NULL;
433
434         if (target->state != TARGET_HALTED)
435         {
436                 LOG_WARNING("target not halted");
437                 return ERROR_TARGET_NOT_HALTED;
438         }
439
440         /* current = 1: continue on current pc, otherwise continue at <address> */
441         if (!current)
442                 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
443
444         /* the front-end may request us not to handle breakpoints */
445         if (handle_breakpoints)
446                 if ((breakpoint = breakpoint_find(target, buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32))))
447                         mips_m4k_unset_breakpoint(target, breakpoint);
448
449         /* restore context */
450         mips32_restore_context(target);
451
452         /* configure single step mode */
453         mips_ejtag_config_step(ejtag_info, 1);
454
455         target->debug_reason = DBG_REASON_SINGLESTEP;
456
457         target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
458
459         /* exit debug mode */
460         mips_ejtag_exit_debug(ejtag_info, 1);
461
462         /* registers are now invalid */
463         mips32_invalidate_core_regs(target);
464
465         if (breakpoint)
466                 mips_m4k_set_breakpoint(target, breakpoint);
467
468         LOG_DEBUG("target stepped ");
469
470         mips_m4k_debug_entry(target);
471         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
472
473         return ERROR_OK;
474 }
475
476 void mips_m4k_enable_breakpoints(struct target_s *target)
477 {
478         breakpoint_t *breakpoint = target->breakpoints;
479
480         /* set any pending breakpoints */
481         while (breakpoint)
482         {
483                 if (breakpoint->set == 0)
484                         mips_m4k_set_breakpoint(target, breakpoint);
485                 breakpoint = breakpoint->next;
486         }
487 }
488
489 int mips_m4k_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
490 {
491         mips32_common_t *mips32 = target->arch_info;
492         mips32_comparator_t * comparator_list = mips32->inst_break_list;
493         int retval;
494         
495         if (breakpoint->set)
496         {
497                 LOG_WARNING("breakpoint already set");
498                 return ERROR_OK;
499         }
500
501         if (breakpoint->type == BKPT_HARD)
502         {
503                 int bp_num = 0;
504
505                 while(comparator_list[bp_num].used && (bp_num < mips32->num_inst_bpoints))
506                         bp_num++;
507                 if (bp_num >= mips32->num_inst_bpoints)
508                 {
509                         LOG_DEBUG("ERROR Can not find free FP Comparator");
510                         LOG_WARNING("ERROR Can not find free FP Comparator");
511                         exit(-1);
512                 }
513                 breakpoint->set = bp_num + 1;
514                 comparator_list[bp_num].used = 1;
515                 comparator_list[bp_num].bp_value = breakpoint->address;
516                 target_write_u32(target, comparator_list[bp_num].reg_address, comparator_list[bp_num].bp_value);
517                 target_write_u32(target, comparator_list[bp_num].reg_address + 0x08, 0x00000000);
518                 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 1);
519                 LOG_DEBUG("bp_num %i bp_value 0x%x", bp_num, comparator_list[bp_num].bp_value);
520         }
521         else if (breakpoint->type == BKPT_SOFT)
522         {
523                 if (breakpoint->length == 4)
524                 {
525                         u32 verify = 0xffffffff;
526                         
527                         if((retval = target->type->read_memory(target, breakpoint->address, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK)
528                         {
529                                 return retval;
530                         }
531                         if ((retval = target_write_u32(target, breakpoint->address, MIPS32_SDBBP)) != ERROR_OK)
532                         {
533                                 return retval;
534                         }
535                         
536                         if ((retval = target_read_u32(target, breakpoint->address, &verify)) != ERROR_OK)
537                         {
538                                 return retval;
539                         }
540                         if (verify != MIPS32_SDBBP)
541                         {
542                                 LOG_ERROR("Unable to set 32bit breakpoint at address %08x - check that memory is read/writable", breakpoint->address);
543                                 return ERROR_OK;
544                         }
545                 }
546                 else
547                 {
548                         u16 verify = 0xffff;
549                         
550                         if((retval = target->type->read_memory(target, breakpoint->address, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK)
551                         {
552                                 return retval;
553                         }
554                         if ((retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP)) != ERROR_OK)
555                         {
556                                 return retval;
557                         }
558                         
559                         if ((retval = target_read_u16(target, breakpoint->address, &verify)) != ERROR_OK)
560                         {
561                                 return retval;
562                         }
563                         if (verify != MIPS16_SDBBP)
564                         {
565                                 LOG_ERROR("Unable to set 16bit breakpoint at address %08x - check that memory is read/writable", breakpoint->address);
566                                 return ERROR_OK;
567                         }
568                 }
569                 
570                 breakpoint->set = 20; /* Any nice value but 0 */
571         }
572
573         return ERROR_OK;
574 }
575
576 int mips_m4k_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
577 {
578         /* get pointers to arch-specific information */
579         mips32_common_t *mips32 = target->arch_info;
580         mips32_comparator_t * comparator_list = mips32->inst_break_list;
581         int retval;
582         
583         if (!breakpoint->set)
584         {
585                 LOG_WARNING("breakpoint not set");
586                 return ERROR_OK;
587         }
588
589         if (breakpoint->type == BKPT_HARD)
590         {
591                 int bp_num = breakpoint->set - 1;
592                 if ((bp_num < 0) || (bp_num >= mips32->num_inst_bpoints))
593                 {
594                         LOG_DEBUG("Invalid FP Comparator number in breakpoint");
595                         return ERROR_OK;
596                 }
597                 comparator_list[bp_num].used = 0;
598                 comparator_list[bp_num].bp_value = 0;
599                 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 0);
600         }
601         else
602         {
603                 /* restore original instruction (kept in target endianness) */
604                 if (breakpoint->length == 4)
605                 {
606                         u32 current_instr;
607                         
608                         /* check that user program has not modified breakpoint instruction */
609                         if ((retval = target->type->read_memory(target, breakpoint->address, 4, 1, (u8*)&current_instr)) != ERROR_OK)
610                         {
611                                 return retval;
612                         }
613                         if (current_instr == MIPS32_SDBBP)
614                         {
615                                 if((retval = target->type->write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
616                                 {
617                                         return retval;
618                                 }
619                         }
620                 }
621                 else
622                 {
623                         u16 current_instr;
624                         
625                         /* check that user program has not modified breakpoint instruction */
626                         if ((retval = target->type->read_memory(target, breakpoint->address, 2, 1, (u8*)&current_instr)) != ERROR_OK)
627                         {
628                                 return retval;
629                         }
630                         
631                         if (current_instr == MIPS16_SDBBP)
632                         {
633                                 if((retval = target->type->write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
634                                 {
635                                         return retval;
636                                 }
637                         }
638                 }
639         }
640         breakpoint->set = 0;
641
642         return ERROR_OK;
643 }
644
645 int mips_m4k_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
646 {
647         mips32_common_t *mips32 = target->arch_info;
648
649         if (breakpoint->type == BKPT_HARD)
650         {
651                 if (mips32->num_inst_bpoints_avail < 1)
652                 {
653                         LOG_INFO("no hardware breakpoint available");
654                         return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
655                 }
656                 
657                 mips32->num_inst_bpoints_avail--;
658         }       
659
660         mips_m4k_set_breakpoint(target, breakpoint);
661
662         return ERROR_OK;
663 }
664
665 int mips_m4k_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
666 {
667         /* get pointers to arch-specific information */
668         mips32_common_t *mips32 = target->arch_info;
669
670         if (target->state != TARGET_HALTED)
671         {
672                 LOG_WARNING("target not halted");
673                 return ERROR_TARGET_NOT_HALTED;
674         }
675
676         if (breakpoint->set)
677         {
678                 mips_m4k_unset_breakpoint(target, breakpoint);
679         }
680
681         if (breakpoint->type == BKPT_HARD)
682                 mips32->num_inst_bpoints_avail++;
683
684         return ERROR_OK;
685 }
686
687 int mips_m4k_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
688 {
689         /* TODO */
690         return ERROR_OK;
691 }
692
693 int mips_m4k_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
694 {
695         /* TODO */
696         return ERROR_OK;
697 }
698
699 int mips_m4k_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
700 {
701         /* TODO */
702         return ERROR_OK;
703 }
704
705 int mips_m4k_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
706 {
707         /* TODO */
708         return ERROR_OK;
709 }
710
711 void mips_m4k_enable_watchpoints(struct target_s *target)
712 {
713         watchpoint_t *watchpoint = target->watchpoints;
714
715         /* set any pending watchpoints */
716         while (watchpoint)
717         {
718                 if (watchpoint->set == 0)
719                         mips_m4k_set_watchpoint(target, watchpoint);
720                 watchpoint = watchpoint->next;
721         }
722 }
723
724 int mips_m4k_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
725 {
726         mips32_common_t *mips32 = target->arch_info;
727         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
728
729         LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
730
731         if (target->state != TARGET_HALTED)
732         {
733                 LOG_WARNING("target not halted");
734                 return ERROR_TARGET_NOT_HALTED;
735         }
736
737         /* sanitize arguments */
738         if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
739                 return ERROR_INVALID_ARGUMENTS;
740
741         if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
742                 return ERROR_TARGET_UNALIGNED_ACCESS;
743
744         switch (size)
745         {
746                 case 4:
747                 case 2:
748                 case 1:
749                         /* if noDMA off, use DMAACC mode for memory read */
750                         if(ejtag_info->impcode & EJTAG_IMP_NODMA)
751                                 return mips32_pracc_read_mem(ejtag_info, address, size, count, (void *)buffer);
752                         else
753                                 return mips32_dmaacc_read_mem(ejtag_info, address, size, count, (void *)buffer);
754                 default:
755                         LOG_ERROR("BUG: we shouldn't get here");
756                         exit(-1);
757                         break;
758         }
759
760         return ERROR_OK;
761 }
762
763 int mips_m4k_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
764 {
765         mips32_common_t *mips32 = target->arch_info;
766         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
767
768         LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
769
770         if (target->state != TARGET_HALTED)
771         {
772                 LOG_WARNING("target not halted");
773                 return ERROR_TARGET_NOT_HALTED;
774         }
775
776         /* sanitize arguments */
777         if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
778                 return ERROR_INVALID_ARGUMENTS;
779
780         if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
781                 return ERROR_TARGET_UNALIGNED_ACCESS;
782
783         switch (size)
784         {
785                 case 4:
786                 case 2:
787                 case 1:
788                         /* if noDMA off, use DMAACC mode for memory write */
789                         if(ejtag_info->impcode & EJTAG_IMP_NODMA)
790                                 mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
791                         else
792                                 mips32_dmaacc_write_mem(ejtag_info, address, size, count, (void *)buffer);
793                         break;
794                 default:
795                         LOG_ERROR("BUG: we shouldn't get here");
796                         exit(-1);
797                         break;
798         }
799
800         return ERROR_OK;
801 }
802
803 int mips_m4k_register_commands(struct command_context_s *cmd_ctx)
804 {
805         int retval;
806
807         retval = mips32_register_commands(cmd_ctx);
808         return retval;
809 }
810
811 int mips_m4k_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
812 {
813         mips32_build_reg_cache(target);
814
815         return ERROR_OK;
816 }
817
818 int mips_m4k_quit(void)
819 {
820         return ERROR_OK;
821 }
822
823 int mips_m4k_init_arch_info(target_t *target, mips_m4k_common_t *mips_m4k, jtag_tap_t *tap)
824 {
825         mips32_common_t *mips32 = &mips_m4k->mips32_common;
826
827         mips_m4k->common_magic = MIPSM4K_COMMON_MAGIC;
828
829         /* initialize mips4k specific info */
830         mips32_init_arch_info(target, mips32, tap);
831         mips32->arch_info = mips_m4k;
832
833         return ERROR_OK;
834 }
835
836 int mips_m4k_target_create(struct target_s *target, Jim_Interp *interp)
837 {
838         mips_m4k_common_t *mips_m4k = calloc(1,sizeof(mips_m4k_common_t));
839
840         mips_m4k_init_arch_info(target, mips_m4k, target->tap);
841
842         return ERROR_OK;
843 }
844
845 int mips_m4k_examine(struct target_s *target)
846 {
847         int retval;
848         mips32_common_t *mips32 = target->arch_info;
849         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
850         u32 idcode = 0;
851
852         if (!target->type->examined)
853         {
854                 mips_ejtag_get_idcode(ejtag_info, &idcode, NULL);
855                 ejtag_info->idcode = idcode;
856                 
857                 if (((idcode >> 1) & 0x7FF) == 0x29)
858                 {
859                         /* we are using a pic32mx so select ejtag port
860                          * as it is not selected by default */
861                         mips_ejtag_set_instr(ejtag_info, 0x05, NULL);
862                         LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
863                 }
864         }
865
866         /* init rest of ejtag interface */
867         if ((retval = mips_ejtag_init(ejtag_info)) != ERROR_OK)
868                 return retval;
869
870         if ((retval = mips32_examine(target)) != ERROR_OK)
871                 return retval;
872
873         return ERROR_OK;
874 }
875
876 int mips_m4k_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
877 {
878         return mips_m4k_write_memory(target, address, 4, count, buffer);
879 }
880
881 int mips_m4k_checksum_memory(target_t *target, u32 address, u32 size, u32 *checksum)
882 {
883         return ERROR_FAIL; /* use bulk read method */
884 }