]> git.sur5r.net Git - openocd/blob - src/target/mips_m4k.c
Change tap_state naming to be consistent with SVF documentation.
[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
54 target_type_t mips_m4k_target =
55 {
56         .name = "mips_m4k",
57
58         .poll = mips_m4k_poll,
59         .arch_state = mips32_arch_state,
60
61         .target_request_data = NULL,
62
63         .halt = mips_m4k_halt,
64         .resume = mips_m4k_resume,
65         .step = mips_m4k_step,
66
67         .assert_reset = mips_m4k_assert_reset,
68         .deassert_reset = mips_m4k_deassert_reset,
69         .soft_reset_halt = mips_m4k_soft_reset_halt,
70
71         .get_gdb_reg_list = mips32_get_gdb_reg_list,
72
73         .read_memory = mips_m4k_read_memory,
74         .write_memory = mips_m4k_write_memory,
75         .bulk_write_memory = mips_m4k_bulk_write_memory,
76         .checksum_memory = NULL,
77         .blank_check_memory = NULL,
78
79         .run_algorithm = mips32_run_algorithm,
80
81         .add_breakpoint = mips_m4k_add_breakpoint,
82         .remove_breakpoint = mips_m4k_remove_breakpoint,
83         .add_watchpoint = mips_m4k_add_watchpoint,
84         .remove_watchpoint = mips_m4k_remove_watchpoint,
85
86         .register_commands = mips_m4k_register_commands,
87         .target_create = mips_m4k_target_create,
88         .init_target = mips_m4k_init_target,
89         .examine = mips_m4k_examine,
90         .quit = mips_m4k_quit
91 };
92
93 int mips_m4k_examine_debug_reason(target_t *target)
94 {
95         int break_status;
96         int retval;
97
98         if ((target->debug_reason != DBG_REASON_DBGRQ)
99                 && (target->debug_reason != DBG_REASON_SINGLESTEP))
100         {
101                 /* get info about inst breakpoint support */
102                 if ((retval = target_read_u32(target, EJTAG_IBS, &break_status)) != ERROR_OK)
103                         return retval;
104                 if (break_status & 0x1f)
105                 {
106                         /* we have halted on a  breakpoint */
107                         if ((retval = target_write_u32(target, EJTAG_IBS, 0)) != ERROR_OK)
108                                 return retval;
109                         target->debug_reason = DBG_REASON_BREAKPOINT;
110                 }
111
112                 /* get info about data breakpoint support */
113                 if ((retval = target_read_u32(target, 0xFF302000, &break_status)) != ERROR_OK)
114                         return retval;
115                 if (break_status & 0x1f)
116                 {
117                         /* we have halted on a  breakpoint */
118                         if ((retval = target_write_u32(target, 0xFF302000, 0)) != ERROR_OK)
119                                 return retval;
120                         target->debug_reason = DBG_REASON_WATCHPOINT;
121                 }
122         }
123
124         return ERROR_OK;
125 }
126
127 int mips_m4k_debug_entry(target_t *target)
128 {
129         mips32_common_t *mips32 = target->arch_info;
130         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
131         u32 debug_reg;
132
133         /* read debug register */
134         mips_ejtag_read_debug(ejtag_info, &debug_reg);
135
136         /* make sure break uit configured */
137         mips32_configure_break_unit(target);
138
139         /* attempt to find halt reason */
140         mips_m4k_examine_debug_reason(target);
141
142         /* clear single step if active */
143         if (debug_reg & EJTAG_DEBUG_DSS)
144         {
145                 /* stopped due to single step - clear step bit */
146                 mips_ejtag_config_step(ejtag_info, 0);
147         }
148
149         mips32_save_context(target);
150
151         LOG_DEBUG("entered debug state at PC 0x%x, target->state: %s",
152                 *(u32*)(mips32->core_cache->reg_list[MIPS32_PC].value),
153                   Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
154
155         return ERROR_OK;
156 }
157
158 int mips_m4k_poll(target_t *target)
159 {
160         int retval;
161         mips32_common_t *mips32 = target->arch_info;
162         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
163         u32 ejtag_ctrl = ejtag_info->ejtag_ctrl;
164
165         /* read ejtag control reg */
166         jtag_add_end_state(TAP_IDLE);
167         mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
168         mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
169
170         /* clear this bit before handling polling
171          * as after reset registers will read zero */
172         if (ejtag_ctrl & EJTAG_CTRL_ROCC)
173         {
174                 /* we have detected a reset, clear flag
175                  * otherwise ejtag will not work */
176                 jtag_add_end_state(TAP_IDLE);
177                 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC;
178
179                 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
180                 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
181                 LOG_DEBUG("Reset Detected");
182         }
183
184         /* check for processor halted */
185         if (ejtag_ctrl & EJTAG_CTRL_BRKST)
186         {
187                 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
188                 {
189                         jtag_add_end_state(TAP_IDLE);
190                         mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT, NULL);
191
192                         target->state = TARGET_HALTED;
193
194                         if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
195                                 return retval;
196
197                         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
198                 }
199                 else if (target->state == TARGET_DEBUG_RUNNING)
200                 {
201                         target->state = TARGET_HALTED;
202
203                         if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
204                                 return retval;
205
206                         target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
207                 }
208         }
209         else
210         {
211                 target->state = TARGET_RUNNING;
212         }
213
214 //      LOG_DEBUG("ctrl=0x%08X", ejtag_ctrl);
215
216         return ERROR_OK;
217 }
218
219 int mips_m4k_halt(struct target_s *target)
220 {
221         mips32_common_t *mips32 = target->arch_info;
222         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
223
224         LOG_DEBUG("target->state: %s",
225                   Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
226
227         if (target->state == TARGET_HALTED)
228         {
229                 LOG_DEBUG("target was already halted");
230                 return ERROR_OK;
231         }
232
233         if (target->state == TARGET_UNKNOWN)
234         {
235                 LOG_WARNING("target was in unknown state when halt was requested");
236         }
237
238         if (target->state == TARGET_RESET)
239         {
240                 if ((jtag_reset_config & RESET_SRST_PULLS_TRST) && jtag_srst)
241                 {
242                         LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
243                         return ERROR_TARGET_FAILURE;
244                 }
245                 else
246                 {
247                         /* we came here in a reset_halt or reset_init sequence
248                          * debug entry was already prepared in mips32_prepare_reset_halt()
249                          */
250                         target->debug_reason = DBG_REASON_DBGRQ;
251
252                         return ERROR_OK;
253                 }
254         }
255
256         /* break processor */
257         mips_ejtag_enter_debug(ejtag_info);
258
259         target->debug_reason = DBG_REASON_DBGRQ;
260
261         return ERROR_OK;
262 }
263
264 int mips_m4k_assert_reset(target_t *target)
265 {
266         mips32_common_t *mips32 = target->arch_info;
267         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
268         mips_m4k_common_t *mips_m4k = mips32->arch_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(mips_m4k->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
494         if (breakpoint->set)
495         {
496                 LOG_WARNING("breakpoint already set");
497                 return ERROR_OK;
498         }
499
500         if (breakpoint->type == BKPT_HARD)
501         {
502                 int bp_num = 0;
503
504                 while(comparator_list[bp_num].used && (bp_num < mips32->num_inst_bpoints))
505                         bp_num++;
506                 if (bp_num >= mips32->num_inst_bpoints)
507                 {
508                         LOG_DEBUG("ERROR Can not find free FP Comparator");
509                         LOG_WARNING("ERROR Can not find free FP Comparator");
510                         exit(-1);
511                 }
512                 breakpoint->set = bp_num + 1;
513                 comparator_list[bp_num].used = 1;
514                 comparator_list[bp_num].bp_value = breakpoint->address;
515                 target_write_u32(target, comparator_list[bp_num].reg_address, comparator_list[bp_num].bp_value);
516                 target_write_u32(target, comparator_list[bp_num].reg_address + 0x08, 0x00000000);
517                 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 1);
518                 LOG_DEBUG("bp_num %i bp_value 0x%x", bp_num, comparator_list[bp_num].bp_value);
519         }
520         else if (breakpoint->type == BKPT_SOFT)
521         {
522
523         }
524
525         return ERROR_OK;
526 }
527
528 int mips_m4k_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
529 {
530         /* get pointers to arch-specific information */
531         mips32_common_t *mips32 = target->arch_info;
532         mips32_comparator_t * comparator_list = mips32->inst_break_list;
533
534         if (!breakpoint->set)
535         {
536                 LOG_WARNING("breakpoint not set");
537                 return ERROR_OK;
538         }
539
540         if (breakpoint->type == BKPT_HARD)
541         {
542                 int bp_num = breakpoint->set - 1;
543                 if ((bp_num < 0) || (bp_num >= mips32->num_inst_bpoints))
544                 {
545                         LOG_DEBUG("Invalid FP Comparator number in breakpoint");
546                         return ERROR_OK;
547                 }
548                 comparator_list[bp_num].used = 0;
549                 comparator_list[bp_num].bp_value = 0;
550                 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 0);
551         }
552         else
553         {
554
555         }
556         breakpoint->set = 0;
557
558         return ERROR_OK;
559 }
560
561 int mips_m4k_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
562 {
563         mips32_common_t *mips32 = target->arch_info;
564
565         if (mips32->num_inst_bpoints_avail < 1)
566         {
567                 LOG_INFO("no hardware breakpoint available");
568                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
569         }
570
571         /* default to hardware for now */
572         breakpoint->type = BKPT_HARD;
573
574         mips32->num_inst_bpoints_avail--;
575         mips_m4k_set_breakpoint(target, breakpoint);
576
577         return ERROR_OK;
578 }
579
580 int mips_m4k_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
581 {
582         /* get pointers to arch-specific information */
583         mips32_common_t *mips32 = target->arch_info;
584
585         if (target->state != TARGET_HALTED)
586         {
587                 LOG_WARNING("target not halted");
588                 return ERROR_TARGET_NOT_HALTED;
589         }
590
591         if (breakpoint->set)
592         {
593                 mips_m4k_unset_breakpoint(target, breakpoint);
594         }
595
596         if (breakpoint->type == BKPT_HARD)
597                 mips32->num_inst_bpoints_avail++;
598
599         return ERROR_OK;
600 }
601
602 int mips_m4k_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
603 {
604         /* TODO */
605         return ERROR_OK;
606 }
607
608 int mips_m4k_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
609 {
610         /* TODO */
611         return ERROR_OK;
612 }
613
614 int mips_m4k_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
615 {
616         /* TODO */
617         return ERROR_OK;
618 }
619
620 int mips_m4k_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
621 {
622         /* TODO */
623         return ERROR_OK;
624 }
625
626 void mips_m4k_enable_watchpoints(struct target_s *target)
627 {
628         watchpoint_t *watchpoint = target->watchpoints;
629
630         /* set any pending watchpoints */
631         while (watchpoint)
632         {
633                 if (watchpoint->set == 0)
634                         mips_m4k_set_watchpoint(target, watchpoint);
635                 watchpoint = watchpoint->next;
636         }
637 }
638
639 int mips_m4k_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
640 {
641         mips32_common_t *mips32 = target->arch_info;
642         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
643
644         LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
645
646         if (target->state != TARGET_HALTED)
647         {
648                 LOG_WARNING("target not halted");
649                 return ERROR_TARGET_NOT_HALTED;
650         }
651
652         /* sanitize arguments */
653         if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
654                 return ERROR_INVALID_ARGUMENTS;
655
656         if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
657                 return ERROR_TARGET_UNALIGNED_ACCESS;
658
659         switch (size)
660         {
661                 case 4:
662                 case 2:
663                 case 1:
664                         /* if noDMA off, use DMAACC mode for memory read */
665                         if(ejtag_info->impcode & EJTAG_IMP_NODMA)
666                                 return mips32_pracc_read_mem(ejtag_info, address, size, count, (void *)buffer);
667                         else
668                                 return mips32_dmaacc_read_mem(ejtag_info, address, size, count, (void *)buffer);
669                 default:
670                         LOG_ERROR("BUG: we shouldn't get here");
671                         exit(-1);
672                         break;
673         }
674
675         return ERROR_OK;
676 }
677
678 int mips_m4k_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
679 {
680         mips32_common_t *mips32 = target->arch_info;
681         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
682
683         LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
684
685         if (target->state != TARGET_HALTED)
686         {
687                 LOG_WARNING("target not halted");
688                 return ERROR_TARGET_NOT_HALTED;
689         }
690
691         /* sanitize arguments */
692         if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
693                 return ERROR_INVALID_ARGUMENTS;
694
695         if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
696                 return ERROR_TARGET_UNALIGNED_ACCESS;
697
698         switch (size)
699         {
700                 case 4:
701                 case 2:
702                 case 1:
703                         /* if noDMA off, use DMAACC mode for memory write */
704                         if(ejtag_info->impcode & EJTAG_IMP_NODMA)
705                                 mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
706                         else
707                                 mips32_dmaacc_write_mem(ejtag_info, address, size, count, (void *)buffer);
708                         break;
709                 default:
710                         LOG_ERROR("BUG: we shouldn't get here");
711                         exit(-1);
712                         break;
713         }
714
715         return ERROR_OK;
716 }
717
718 int mips_m4k_register_commands(struct command_context_s *cmd_ctx)
719 {
720         int retval;
721
722         retval = mips32_register_commands(cmd_ctx);
723         return retval;
724 }
725
726 int mips_m4k_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
727 {
728         mips32_build_reg_cache(target);
729
730         return ERROR_OK;
731 }
732
733 int mips_m4k_quit(void)
734 {
735         return ERROR_OK;
736 }
737
738 int mips_m4k_init_arch_info(target_t *target, mips_m4k_common_t *mips_m4k, jtag_tap_t *tap, const char *variant)
739 {
740         mips32_common_t *mips32 = &mips_m4k->mips32_common;
741
742         if (variant)
743         {
744                 mips_m4k->variant = strdup(variant);
745         }
746         else
747         {
748                 mips_m4k->variant = strdup("");
749         }
750
751         mips_m4k->common_magic = MIPSM4K_COMMON_MAGIC;
752
753         /* initialize mips4k specific info */
754         mips32_init_arch_info(target, mips32, tap, variant);
755         mips32->arch_info = mips_m4k;
756
757         return ERROR_OK;
758 }
759
760 int mips_m4k_target_create(struct target_s *target, Jim_Interp *interp)
761 {
762         mips_m4k_common_t *mips_m4k = calloc(1,sizeof(mips_m4k_common_t));
763
764         mips_m4k_init_arch_info(target, mips_m4k, target->tap, target->variant);
765
766         return ERROR_OK;
767 }
768
769 int mips_m4k_examine(struct target_s *target)
770 {
771         int retval;
772         mips32_common_t *mips32 = target->arch_info;
773         mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
774         u32 idcode = 0;
775
776         if (!target->type->examined)
777         {
778                 mips_ejtag_get_idcode(ejtag_info, &idcode, NULL);
779
780                 if (((idcode >> 1) & 0x7FF) == 0x29)
781                 {
782                         /* we are using a pic32mx so select ejtag port
783                          * as it is not selected by default */
784                         mips_ejtag_set_instr(ejtag_info, 0x05, NULL);
785                         LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
786                 }
787         }
788
789         /* init rest of ejtag interface */
790         if ((retval = mips_ejtag_init(ejtag_info)) != ERROR_OK)
791                 return retval;
792
793         if ((retval = mips32_examine(target)) != ERROR_OK)
794                 return retval;
795
796         return ERROR_OK;
797 }
798
799 int mips_m4k_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
800 {
801         return mips_m4k_write_memory(target, address, 4, count, buffer);
802 }