]> git.sur5r.net Git - openocd/blob - src/target/mips_m4k.c
mips: fix some more endian madness
[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  *   Copyright (C) 2009 by David N. Claffey <dnclaffey@gmail.com>          *
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  *   This program is distributed in the hope that it will be useful,       *
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
17  *   GNU General Public License for more details.                          *
18  *                                                                         *
19  *   You should have received a copy of the GNU General Public License     *
20  *   along with this program; if not, write to the                         *
21  *   Free Software Foundation, Inc.,                                       *
22  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
23  ***************************************************************************/
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "breakpoints.h"
29 #include "mips32.h"
30 #include "mips_m4k.h"
31 #include "mips32_dmaacc.h"
32 #include "target_type.h"
33 #include "register.h"
34
35 static void mips_m4k_enable_breakpoints(struct target *target);
36 static void mips_m4k_enable_watchpoints(struct target *target);
37 static int mips_m4k_set_breakpoint(struct target *target,
38                 struct breakpoint *breakpoint);
39 static int mips_m4k_unset_breakpoint(struct target *target,
40                 struct breakpoint *breakpoint);
41
42 static int mips_m4k_examine_debug_reason(struct target *target)
43 {
44         uint32_t break_status;
45         int retval;
46
47         if ((target->debug_reason != DBG_REASON_DBGRQ)
48                 && (target->debug_reason != DBG_REASON_SINGLESTEP))
49         {
50                 /* get info about inst breakpoint support */
51                 if ((retval = target_read_u32(target, EJTAG_IBS, &break_status)) != ERROR_OK)
52                         return retval;
53                 if (break_status & 0x1f)
54                 {
55                         /* we have halted on a  breakpoint */
56                         if ((retval = target_write_u32(target, EJTAG_IBS, 0)) != ERROR_OK)
57                                 return retval;
58                         target->debug_reason = DBG_REASON_BREAKPOINT;
59                 }
60
61                 /* get info about data breakpoint support */
62                 if ((retval = target_read_u32(target, EJTAG_DBS, &break_status)) != ERROR_OK)
63                         return retval;
64                 if (break_status & 0x1f)
65                 {
66                         /* we have halted on a  breakpoint */
67                         if ((retval = target_write_u32(target, EJTAG_DBS, 0)) != ERROR_OK)
68                                 return retval;
69                         target->debug_reason = DBG_REASON_WATCHPOINT;
70                 }
71         }
72
73         return ERROR_OK;
74 }
75
76 static int mips_m4k_debug_entry(struct target *target)
77 {
78         struct mips32_common *mips32 = target_to_mips32(target);
79         struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
80         uint32_t debug_reg;
81
82         /* read debug register */
83         mips_ejtag_read_debug(ejtag_info, &debug_reg);
84
85         /* make sure break unit configured */
86         mips32_configure_break_unit(target);
87
88         /* attempt to find halt reason */
89         mips_m4k_examine_debug_reason(target);
90
91         /* clear single step if active */
92         if (debug_reg & EJTAG_DEBUG_DSS)
93         {
94                 /* stopped due to single step - clear step bit */
95                 mips_ejtag_config_step(ejtag_info, 0);
96         }
97
98         mips32_save_context(target);
99
100         /* default to mips32 isa, it will be changed below if required */
101         mips32->isa_mode = MIPS32_ISA_MIPS32;
102
103         if (ejtag_info->impcode & EJTAG_IMP_MIPS16) {
104                 mips32->isa_mode = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1);
105         }
106
107         LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s",
108                         buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32),
109                         target_state_name(target));
110
111         return ERROR_OK;
112 }
113
114 static int mips_m4k_poll(struct target *target)
115 {
116         int retval;
117         struct mips32_common *mips32 = target_to_mips32(target);
118         struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
119         uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl;
120
121         /* read ejtag control reg */
122         mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
123         retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
124         if (retval != ERROR_OK)
125                 return retval;
126
127         /* clear this bit before handling polling
128          * as after reset registers will read zero */
129         if (ejtag_ctrl & EJTAG_CTRL_ROCC)
130         {
131                 /* we have detected a reset, clear flag
132                  * otherwise ejtag will not work */
133                 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC;
134
135                 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
136                 retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
137                 if (retval != ERROR_OK)
138                         return retval;
139                 LOG_DEBUG("Reset Detected");
140         }
141
142         /* check for processor halted */
143         if (ejtag_ctrl & EJTAG_CTRL_BRKST)
144         {
145                 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
146                 {
147                         mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT);
148
149                         target->state = TARGET_HALTED;
150
151                         if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
152                                 return retval;
153
154                         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
155                 }
156                 else if (target->state == TARGET_DEBUG_RUNNING)
157                 {
158                         target->state = TARGET_HALTED;
159
160                         if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
161                                 return retval;
162
163                         target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
164                 }
165         }
166         else
167         {
168                 target->state = TARGET_RUNNING;
169         }
170
171 //      LOG_DEBUG("ctrl = 0x%08X", ejtag_ctrl);
172
173         return ERROR_OK;
174 }
175
176 static int mips_m4k_halt(struct target *target)
177 {
178         struct mips32_common *mips32 = target_to_mips32(target);
179         struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
180
181         LOG_DEBUG("target->state: %s",
182                   target_state_name(target));
183
184         if (target->state == TARGET_HALTED)
185         {
186                 LOG_DEBUG("target was already halted");
187                 return ERROR_OK;
188         }
189
190         if (target->state == TARGET_UNKNOWN)
191         {
192                 LOG_WARNING("target was in unknown state when halt was requested");
193         }
194
195         if (target->state == TARGET_RESET)
196         {
197                 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst())
198                 {
199                         LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
200                         return ERROR_TARGET_FAILURE;
201                 }
202                 else
203                 {
204                         /* we came here in a reset_halt or reset_init sequence
205                          * debug entry was already prepared in mips32_prepare_reset_halt()
206                          */
207                         target->debug_reason = DBG_REASON_DBGRQ;
208
209                         return ERROR_OK;
210                 }
211         }
212
213         /* break processor */
214         mips_ejtag_enter_debug(ejtag_info);
215
216         target->debug_reason = DBG_REASON_DBGRQ;
217
218         return ERROR_OK;
219 }
220
221 static int mips_m4k_assert_reset(struct target *target)
222 {
223         struct mips_m4k_common *mips_m4k = target_to_m4k(target);
224         struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
225         int assert_srst = 1;
226
227         LOG_DEBUG("target->state: %s",
228                 target_state_name(target));
229
230         enum reset_types jtag_reset_config = jtag_get_reset_config();
231
232         if (!(jtag_reset_config & RESET_HAS_SRST))
233                 assert_srst = 0;
234
235         if (target->reset_halt)
236         {
237                 /* use hardware to catch reset */
238                 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT);
239         }
240         else
241         {
242                 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT);
243         }
244
245         if (assert_srst)
246         {
247                 /* here we should issue a srst only, but we may have to assert trst as well */
248                 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
249                 {
250                         jtag_add_reset(1, 1);
251                 }
252                 else
253                 {
254                         jtag_add_reset(0, 1);
255                 }
256         }
257         else
258         {
259                 if (mips_m4k->is_pic32mx)
260                 {
261                         LOG_DEBUG("Using MTAP reset to reset processor...");
262
263                         /* use microchip specific MTAP reset */
264                         mips_ejtag_set_instr(ejtag_info, MTAP_SW_MTAP);
265                         mips_ejtag_set_instr(ejtag_info, MTAP_COMMAND);
266
267                         mips_ejtag_drscan_8_out(ejtag_info, MCHP_ASERT_RST);
268                         mips_ejtag_drscan_8_out(ejtag_info, MCHP_DE_ASSERT_RST);
269                         mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);
270                 }
271                 else
272                 {
273                         /* use ejtag reset - not supported by all cores */
274                         uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_PRRST | EJTAG_CTRL_PERRST;
275                         LOG_DEBUG("Using EJTAG reset (PRRST) to reset processor...");
276                         mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
277                         mips_ejtag_drscan_32_out(ejtag_info, ejtag_ctrl);
278                 }
279         }
280
281         target->state = TARGET_RESET;
282         jtag_add_sleep(50000);
283
284         register_cache_invalidate(mips_m4k->mips32.core_cache);
285
286         if (target->reset_halt)
287         {
288                 int retval;
289                 if ((retval = target_halt(target)) != ERROR_OK)
290                         return retval;
291         }
292
293         return ERROR_OK;
294 }
295
296 static int mips_m4k_deassert_reset(struct target *target)
297 {
298         LOG_DEBUG("target->state: %s",
299                 target_state_name(target));
300
301         /* deassert reset lines */
302         jtag_add_reset(0, 0);
303
304         return ERROR_OK;
305 }
306
307 static int mips_m4k_soft_reset_halt(struct target *target)
308 {
309         /* TODO */
310         return ERROR_OK;
311 }
312
313 static int mips_m4k_single_step_core(struct target *target)
314 {
315         struct mips32_common *mips32 = target_to_mips32(target);
316         struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
317
318         /* configure single step mode */
319         mips_ejtag_config_step(ejtag_info, 1);
320
321         /* disable interrupts while stepping */
322         mips32_enable_interrupts(target, 0);
323
324         /* exit debug mode */
325         mips_ejtag_exit_debug(ejtag_info);
326
327         mips_m4k_debug_entry(target);
328
329         return ERROR_OK;
330 }
331
332 static int mips_m4k_resume(struct target *target, int current,
333                 uint32_t address, int handle_breakpoints, int debug_execution)
334 {
335         struct mips32_common *mips32 = target_to_mips32(target);
336         struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
337         struct breakpoint *breakpoint = NULL;
338         uint32_t resume_pc;
339
340         if (target->state != TARGET_HALTED)
341         {
342                 LOG_WARNING("target not halted");
343                 return ERROR_TARGET_NOT_HALTED;
344         }
345
346         if (!debug_execution)
347         {
348                 target_free_all_working_areas(target);
349                 mips_m4k_enable_breakpoints(target);
350                 mips_m4k_enable_watchpoints(target);
351         }
352
353         /* current = 1: continue on current pc, otherwise continue at <address> */
354         if (!current)
355         {
356                 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
357                 mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
358                 mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
359         }
360
361         if (ejtag_info->impcode & EJTAG_IMP_MIPS16) {
362                 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1, mips32->isa_mode);
363         }
364
365         resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
366
367         mips32_restore_context(target);
368
369         /* the front-end may request us not to handle breakpoints */
370         if (handle_breakpoints)
371         {
372                 /* Single step past breakpoint at current address */
373                 if ((breakpoint = breakpoint_find(target, resume_pc)))
374                 {
375                         LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
376                         mips_m4k_unset_breakpoint(target, breakpoint);
377                         mips_m4k_single_step_core(target);
378                         mips_m4k_set_breakpoint(target, breakpoint);
379                 }
380         }
381
382         /* enable interrupts if we are running */
383         mips32_enable_interrupts(target, !debug_execution);
384
385         /* exit debug mode */
386         mips_ejtag_exit_debug(ejtag_info);
387         target->debug_reason = DBG_REASON_NOTHALTED;
388
389         /* registers are now invalid */
390         register_cache_invalidate(mips32->core_cache);
391
392         if (!debug_execution)
393         {
394                 target->state = TARGET_RUNNING;
395                 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
396                 LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
397         }
398         else
399         {
400                 target->state = TARGET_DEBUG_RUNNING;
401                 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
402                 LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
403         }
404
405         return ERROR_OK;
406 }
407
408 static int mips_m4k_step(struct target *target, int current,
409                 uint32_t address, int handle_breakpoints)
410 {
411         /* get pointers to arch-specific information */
412         struct mips32_common *mips32 = target_to_mips32(target);
413         struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
414         struct breakpoint *breakpoint = NULL;
415
416         if (target->state != TARGET_HALTED)
417         {
418                 LOG_WARNING("target not halted");
419                 return ERROR_TARGET_NOT_HALTED;
420         }
421
422         /* current = 1: continue on current pc, otherwise continue at <address> */
423         if (!current)
424         {
425                 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
426                 mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
427                 mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
428         }
429
430         /* the front-end may request us not to handle breakpoints */
431         if (handle_breakpoints) {
432                 breakpoint = breakpoint_find(target,
433                                 buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32));
434                 if (breakpoint)
435                         mips_m4k_unset_breakpoint(target, breakpoint);
436         }
437
438         /* restore context */
439         mips32_restore_context(target);
440
441         /* configure single step mode */
442         mips_ejtag_config_step(ejtag_info, 1);
443
444         target->debug_reason = DBG_REASON_SINGLESTEP;
445
446         target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
447
448         /* disable interrupts while stepping */
449         mips32_enable_interrupts(target, 0);
450
451         /* exit debug mode */
452         mips_ejtag_exit_debug(ejtag_info);
453
454         /* registers are now invalid */
455         register_cache_invalidate(mips32->core_cache);
456
457         if (breakpoint)
458                 mips_m4k_set_breakpoint(target, breakpoint);
459
460         LOG_DEBUG("target stepped ");
461
462         mips_m4k_debug_entry(target);
463         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
464
465         return ERROR_OK;
466 }
467
468 static void mips_m4k_enable_breakpoints(struct target *target)
469 {
470         struct breakpoint *breakpoint = target->breakpoints;
471
472         /* set any pending breakpoints */
473         while (breakpoint)
474         {
475                 if (breakpoint->set == 0)
476                         mips_m4k_set_breakpoint(target, breakpoint);
477                 breakpoint = breakpoint->next;
478         }
479 }
480
481 static int mips_m4k_set_breakpoint(struct target *target,
482                 struct breakpoint *breakpoint)
483 {
484         struct mips32_common *mips32 = target_to_mips32(target);
485         struct mips32_comparator * comparator_list = mips32->inst_break_list;
486         int retval;
487
488         if (breakpoint->set)
489         {
490                 LOG_WARNING("breakpoint already set");
491                 return ERROR_OK;
492         }
493
494         if (breakpoint->type == BKPT_HARD)
495         {
496                 int bp_num = 0;
497
498                 while (comparator_list[bp_num].used && (bp_num < mips32->num_inst_bpoints))
499                         bp_num++;
500                 if (bp_num >= mips32->num_inst_bpoints)
501                 {
502                         LOG_ERROR("Can not find free FP Comparator(bpid: %d)",
503                                           breakpoint->unique_id );
504                         return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
505                 }
506                 breakpoint->set = bp_num + 1;
507                 comparator_list[bp_num].used = 1;
508                 comparator_list[bp_num].bp_value = breakpoint->address;
509                 target_write_u32(target, comparator_list[bp_num].reg_address, comparator_list[bp_num].bp_value);
510                 target_write_u32(target, comparator_list[bp_num].reg_address + 0x08, 0x00000000);
511                 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 1);
512                 LOG_DEBUG("bpid: %d, bp_num %i bp_value 0x%" PRIx32 "",
513                                   breakpoint->unique_id,
514                                   bp_num, comparator_list[bp_num].bp_value);
515         }
516         else if (breakpoint->type == BKPT_SOFT)
517         {
518                 LOG_DEBUG("bpid: %d", breakpoint->unique_id );
519                 if (breakpoint->length == 4)
520                 {
521                         uint32_t verify = 0xffffffff;
522
523                         if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1,
524                                         breakpoint->orig_instr)) != ERROR_OK)
525                         {
526                                 return retval;
527                         }
528                         if ((retval = target_write_u32(target, breakpoint->address, MIPS32_SDBBP)) != ERROR_OK)
529                         {
530                                 return retval;
531                         }
532
533                         if ((retval = target_read_u32(target, breakpoint->address, &verify)) != ERROR_OK)
534                         {
535                                 return retval;
536                         }
537                         if (verify != MIPS32_SDBBP)
538                         {
539                                 LOG_ERROR("Unable to set 32bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address);
540                                 return ERROR_OK;
541                         }
542                 }
543                 else
544                 {
545                         uint16_t verify = 0xffff;
546
547                         if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1,
548                                         breakpoint->orig_instr)) != ERROR_OK)
549                         {
550                                 return retval;
551                         }
552                         if ((retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP)) != ERROR_OK)
553                         {
554                                 return retval;
555                         }
556
557                         if ((retval = target_read_u16(target, breakpoint->address, &verify)) != ERROR_OK)
558                         {
559                                 return retval;
560                         }
561                         if (verify != MIPS16_SDBBP)
562                         {
563                                 LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address);
564                                 return ERROR_OK;
565                         }
566                 }
567
568                 breakpoint->set = 20; /* Any nice value but 0 */
569         }
570
571         return ERROR_OK;
572 }
573
574 static int mips_m4k_unset_breakpoint(struct target *target,
575                 struct breakpoint *breakpoint)
576 {
577         /* get pointers to arch-specific information */
578         struct mips32_common *mips32 = target_to_mips32(target);
579         struct mips32_comparator *comparator_list = mips32->inst_break_list;
580         int retval;
581
582         if (!breakpoint->set)
583         {
584                 LOG_WARNING("breakpoint not set");
585                 return ERROR_OK;
586         }
587
588         if (breakpoint->type == BKPT_HARD)
589         {
590                 int bp_num = breakpoint->set - 1;
591                 if ((bp_num < 0) || (bp_num >= mips32->num_inst_bpoints))
592                 {
593                         LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %d)",
594                                           breakpoint->unique_id);
595                         return ERROR_OK;
596                 }
597                 LOG_DEBUG("bpid: %d - releasing hw: %d",
598                                   breakpoint->unique_id,
599                                   bp_num );
600                 comparator_list[bp_num].used = 0;
601                 comparator_list[bp_num].bp_value = 0;
602                 target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 0);
603
604         }
605         else
606         {
607                 /* restore original instruction (kept in target endianness) */
608                 LOG_DEBUG("bpid: %d", breakpoint->unique_id);
609                 if (breakpoint->length == 4)
610                 {
611                         uint32_t current_instr;
612
613                         /* check that user program has not modified breakpoint instruction */
614                         if ((retval = target_read_memory(target, breakpoint->address, 4, 1,
615                                         (uint8_t*)&current_instr)) != ERROR_OK)
616                         {
617                                 return retval;
618                         }
619                         if (current_instr == MIPS32_SDBBP)
620                         {
621                                 if ((retval = target_write_memory(target, breakpoint->address, 4, 1,
622                                                 breakpoint->orig_instr)) != ERROR_OK)
623                                 {
624                                         return retval;
625                                 }
626                         }
627                 }
628                 else
629                 {
630                         uint16_t current_instr;
631
632                         /* check that user program has not modified breakpoint instruction */
633                         if ((retval = target_read_memory(target, breakpoint->address, 2, 1,
634                                         (uint8_t*)&current_instr)) != ERROR_OK)
635                         {
636                                 return retval;
637                         }
638
639                         if (current_instr == MIPS16_SDBBP)
640                         {
641                                 if ((retval = target_write_memory(target, breakpoint->address, 2, 1,
642                                                 breakpoint->orig_instr)) != ERROR_OK)
643                                 {
644                                         return retval;
645                                 }
646                         }
647                 }
648         }
649         breakpoint->set = 0;
650
651         return ERROR_OK;
652 }
653
654 static int mips_m4k_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
655 {
656         struct mips32_common *mips32 = target_to_mips32(target);
657
658         if (breakpoint->type == BKPT_HARD)
659         {
660                 if (mips32->num_inst_bpoints_avail < 1)
661                 {
662                         LOG_INFO("no hardware breakpoint available");
663                         return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
664                 }
665
666                 mips32->num_inst_bpoints_avail--;
667         }
668
669         return mips_m4k_set_breakpoint(target, breakpoint);
670 }
671
672 static int mips_m4k_remove_breakpoint(struct target *target,
673                 struct breakpoint *breakpoint)
674 {
675         /* get pointers to arch-specific information */
676         struct mips32_common *mips32 = target_to_mips32(target);
677
678         if (target->state != TARGET_HALTED)
679         {
680                 LOG_WARNING("target not halted");
681                 return ERROR_TARGET_NOT_HALTED;
682         }
683
684         if (breakpoint->set)
685         {
686                 mips_m4k_unset_breakpoint(target, breakpoint);
687         }
688
689         if (breakpoint->type == BKPT_HARD)
690                 mips32->num_inst_bpoints_avail++;
691
692         return ERROR_OK;
693 }
694
695 static int mips_m4k_set_watchpoint(struct target *target,
696                 struct watchpoint *watchpoint)
697 {
698         struct mips32_common *mips32 = target_to_mips32(target);
699         struct mips32_comparator *comparator_list = mips32->data_break_list;
700         int wp_num = 0;
701         /*
702          * watchpoint enabled, ignore all byte lanes in value register
703          * and exclude both load and store accesses from  watchpoint
704          * condition evaluation
705         */
706         int enable = EJTAG_DBCn_NOSB | EJTAG_DBCn_NOLB | EJTAG_DBCn_BE |
707                 (0xff << EJTAG_DBCn_BLM_SHIFT);
708
709         if (watchpoint->set)
710         {
711                 LOG_WARNING("watchpoint already set");
712                 return ERROR_OK;
713         }
714
715         while(comparator_list[wp_num].used && (wp_num < mips32->num_data_bpoints))
716                 wp_num++;
717         if (wp_num >= mips32->num_data_bpoints)
718         {
719                 LOG_ERROR("Can not find free FP Comparator");
720                 return ERROR_FAIL;
721         }
722
723         if (watchpoint->length != 4)
724         {
725                 LOG_ERROR("Only watchpoints of length 4 are supported");
726                 return ERROR_TARGET_UNALIGNED_ACCESS;
727         }
728
729         if (watchpoint->address % 4)
730         {
731                 LOG_ERROR("Watchpoints address should be word aligned");
732                 return ERROR_TARGET_UNALIGNED_ACCESS;
733         }
734
735         switch (watchpoint->rw)
736         {
737                 case WPT_READ:
738                         enable &= ~EJTAG_DBCn_NOLB;
739                         break;
740                 case WPT_WRITE:
741                         enable &= ~EJTAG_DBCn_NOSB;
742                         break;
743                 case WPT_ACCESS:
744                         enable &= ~(EJTAG_DBCn_NOLB | EJTAG_DBCn_NOSB);
745                         break;
746                 default:
747                         LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
748         }
749
750         watchpoint->set = wp_num + 1;
751         comparator_list[wp_num].used = 1;
752         comparator_list[wp_num].bp_value = watchpoint->address;
753         target_write_u32(target, comparator_list[wp_num].reg_address, comparator_list[wp_num].bp_value);
754         target_write_u32(target, comparator_list[wp_num].reg_address + 0x08, 0x00000000);
755         target_write_u32(target, comparator_list[wp_num].reg_address + 0x10, 0x00000000);
756         target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, enable);
757         target_write_u32(target, comparator_list[wp_num].reg_address + 0x20, 0);
758         LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "", wp_num, comparator_list[wp_num].bp_value);
759
760         return ERROR_OK;
761 }
762
763 static int mips_m4k_unset_watchpoint(struct target *target,
764                 struct watchpoint *watchpoint)
765 {
766         /* get pointers to arch-specific information */
767         struct mips32_common *mips32 = target_to_mips32(target);
768         struct mips32_comparator *comparator_list = mips32->data_break_list;
769
770         if (!watchpoint->set)
771         {
772                 LOG_WARNING("watchpoint not set");
773                 return ERROR_OK;
774         }
775
776         int wp_num = watchpoint->set - 1;
777         if ((wp_num < 0) || (wp_num >= mips32->num_data_bpoints))
778         {
779                 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
780                 return ERROR_OK;
781         }
782         comparator_list[wp_num].used = 0;
783         comparator_list[wp_num].bp_value = 0;
784         target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, 0);
785         watchpoint->set = 0;
786
787         return ERROR_OK;
788 }
789
790 static int mips_m4k_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
791 {
792         struct mips32_common *mips32 = target_to_mips32(target);
793
794         if (mips32->num_data_bpoints_avail < 1)
795         {
796                 LOG_INFO("no hardware watchpoints available");
797                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
798         }
799
800         mips32->num_data_bpoints_avail--;
801
802         mips_m4k_set_watchpoint(target, watchpoint);
803         return ERROR_OK;
804 }
805
806 static int mips_m4k_remove_watchpoint(struct target *target,
807                 struct watchpoint *watchpoint)
808 {
809         /* get pointers to arch-specific information */
810         struct mips32_common *mips32 = target_to_mips32(target);
811
812         if (target->state != TARGET_HALTED)
813         {
814                 LOG_WARNING("target not halted");
815                 return ERROR_TARGET_NOT_HALTED;
816         }
817
818         if (watchpoint->set)
819         {
820                 mips_m4k_unset_watchpoint(target, watchpoint);
821         }
822
823         mips32->num_data_bpoints_avail++;
824
825         return ERROR_OK;
826 }
827
828 static void mips_m4k_enable_watchpoints(struct target *target)
829 {
830         struct watchpoint *watchpoint = target->watchpoints;
831
832         /* set any pending watchpoints */
833         while (watchpoint)
834         {
835                 if (watchpoint->set == 0)
836                         mips_m4k_set_watchpoint(target, watchpoint);
837                 watchpoint = watchpoint->next;
838         }
839 }
840
841 static int mips_m4k_read_memory(struct target *target, uint32_t address,
842                 uint32_t size, uint32_t count, uint8_t *buffer)
843 {
844         struct mips32_common *mips32 = target_to_mips32(target);
845         struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
846
847         LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count);
848
849         if (target->state != TARGET_HALTED)
850         {
851                 LOG_WARNING("target not halted");
852                 return ERROR_TARGET_NOT_HALTED;
853         }
854
855         /* sanitize arguments */
856         if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
857                 return ERROR_INVALID_ARGUMENTS;
858
859         if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
860                 return ERROR_TARGET_UNALIGNED_ACCESS;
861
862         /* if noDMA off, use DMAACC mode for memory read */
863         int retval;
864         if (ejtag_info->impcode & EJTAG_IMP_NODMA)
865                 retval = mips32_pracc_read_mem(ejtag_info, address, size, count, (void *)buffer);
866         else
867                 retval = mips32_dmaacc_read_mem(ejtag_info, address, size, count, (void *)buffer);
868         if (ERROR_OK != retval)
869                 return retval;
870
871         /* mips32_..._read_mem with size 4/2 returns uint32_t/uint16_t in host */
872         /* endianness, but byte array should represent target endianness       */
873         uint32_t i, t32;
874         uint16_t t16;
875         for(i = 0; i < (count*size); i += size)
876         {
877                 switch(size)
878                 {
879                 case 4:
880                         t32 = *(uint32_t*)&buffer[i];
881                         target_buffer_set_u32(target,&buffer[i], t32);
882                         break;
883                 case 2:
884                         t16 = *(uint16_t*)&buffer[i];
885                         target_buffer_set_u16(target,&buffer[i], t16);
886                         break;
887                 }
888         }
889
890         return ERROR_OK;
891 }
892
893 static int mips_m4k_write_memory(struct target *target, uint32_t address,
894                 uint32_t size, uint32_t count, const uint8_t *buffer)
895 {
896         struct mips32_common *mips32 = target_to_mips32(target);
897         struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
898
899         LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
900                         address, size, count);
901
902         if (target->state != TARGET_HALTED)
903         {
904                 LOG_WARNING("target not halted");
905                 return ERROR_TARGET_NOT_HALTED;
906         }
907
908         /* sanitize arguments */
909         if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
910                 return ERROR_INVALID_ARGUMENTS;
911
912         if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
913                 return ERROR_TARGET_UNALIGNED_ACCESS;
914
915         /* mips32_..._write_mem with size 4/2 requires uint32_t/uint16_t in host */
916         /* endianness, but byte array represents target endianness               */
917         uint8_t * t = NULL;
918         t = malloc(count * sizeof(uint32_t));
919         if (t == NULL)
920         {
921                 LOG_ERROR("Out of memory");
922                 return ERROR_FAIL;
923         }
924
925         uint32_t i, t32;
926         uint16_t t16;
927         for(i = 0; i < (count*size); i += size)
928         {
929                 switch(size)
930                 {
931                 case 4:
932                         t32 = target_buffer_get_u32(target,&buffer[i]);
933                         *(uint32_t*)&t[i] = t32;
934                         break;
935                 case 2:
936                         t16 = target_buffer_get_u16(target,&buffer[i]);
937                         *(uint16_t*)&t[i] = t16;
938                         break;
939                 }
940         }
941         buffer = t;
942
943         /* if noDMA off, use DMAACC mode for memory write */
944         int retval;
945         if (ejtag_info->impcode & EJTAG_IMP_NODMA)
946                 retval = mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
947         else
948                 retval = mips32_dmaacc_write_mem(ejtag_info, address, size, count, (void *)buffer);
949
950         if (t != NULL)
951                 free(t);
952
953         if (ERROR_OK != retval)
954                 return retval;
955
956         return ERROR_OK;
957 }
958
959 static int mips_m4k_init_target(struct command_context *cmd_ctx,
960                 struct target *target)
961 {
962         mips32_build_reg_cache(target);
963
964         return ERROR_OK;
965 }
966
967 static int mips_m4k_init_arch_info(struct target *target,
968                 struct mips_m4k_common *mips_m4k, struct jtag_tap *tap)
969 {
970         struct mips32_common *mips32 = &mips_m4k->mips32;
971
972         mips_m4k->common_magic = MIPSM4K_COMMON_MAGIC;
973
974         /* initialize mips4k specific info */
975         mips32_init_arch_info(target, mips32, tap);
976         mips32->arch_info = mips_m4k;
977
978         return ERROR_OK;
979 }
980
981 static int mips_m4k_target_create(struct target *target, Jim_Interp *interp)
982 {
983         struct mips_m4k_common *mips_m4k = calloc(1, sizeof(struct mips_m4k_common));
984
985         mips_m4k_init_arch_info(target, mips_m4k, target->tap);
986
987         return ERROR_OK;
988 }
989
990 static int mips_m4k_examine(struct target *target)
991 {
992         int retval;
993         struct mips_m4k_common *mips_m4k = target_to_m4k(target);
994         struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
995         uint32_t idcode = 0;
996
997         if (!target_was_examined(target))
998         {
999                 retval = mips_ejtag_get_idcode(ejtag_info, &idcode);
1000                 if (retval != ERROR_OK)
1001                         return retval;
1002                 ejtag_info->idcode = idcode;
1003
1004                 if (((idcode >> 1) & 0x7FF) == 0x29)
1005                 {
1006                         /* we are using a pic32mx so select ejtag port
1007                          * as it is not selected by default */
1008                         mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);
1009                         LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
1010                         mips_m4k->is_pic32mx = true;
1011                 }
1012         }
1013
1014         /* init rest of ejtag interface */
1015         if ((retval = mips_ejtag_init(ejtag_info)) != ERROR_OK)
1016                 return retval;
1017
1018         if ((retval = mips32_examine(target)) != ERROR_OK)
1019                 return retval;
1020
1021         return ERROR_OK;
1022 }
1023
1024 static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
1025                 uint32_t count, const uint8_t *buffer)
1026 {
1027         struct mips32_common *mips32 = target_to_mips32(target);
1028         struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
1029         int retval;
1030         int write_t = 1;
1031
1032         LOG_DEBUG("address: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, count);
1033
1034         if (target->state != TARGET_HALTED)
1035         {
1036                 LOG_WARNING("target not halted");
1037                 return ERROR_TARGET_NOT_HALTED;
1038         }
1039
1040         /* check alignment */
1041         if (address & 0x3u)
1042                 return ERROR_TARGET_UNALIGNED_ACCESS;
1043
1044         if (mips32->fast_data_area == NULL)
1045         {
1046                 /* Get memory for block write handler
1047                  * we preserve this area between calls and gain a speed increase
1048                  * of about 3kb/sec when writing flash
1049                  * this will be released/nulled by the system when the target is resumed or reset */
1050                 retval = target_alloc_working_area(target,
1051                                 MIPS32_FASTDATA_HANDLER_SIZE,
1052                                 &mips32->fast_data_area);
1053                 if (retval != ERROR_OK)
1054                 {
1055                         LOG_WARNING("No working area available, falling back to non-bulk write");
1056                         return mips_m4k_write_memory(target, address, 4, count, buffer);
1057                 }
1058
1059                 /* reset fastadata state so the algo get reloaded */
1060                 ejtag_info->fast_access_save = -1;
1061         }
1062
1063         /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */
1064         /* but byte array represents target endianness                      */
1065         uint8_t * t = NULL;
1066         t = malloc(count * sizeof(uint32_t));
1067         if (t == NULL)
1068         {
1069                 LOG_ERROR("Out of memory");
1070                 return ERROR_FAIL;
1071         }
1072
1073         uint32_t i, t32;
1074         for(i = 0; i < (count*4); i += 4)
1075         {
1076                 t32 = target_buffer_get_u32(target,&buffer[i]);
1077                 *(uint32_t*)&t[i] = t32;
1078         }
1079         
1080         retval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, write_t, address,
1081                         count, (uint32_t*) (void *)t);
1082
1083         if (t != NULL)
1084                 free(t);
1085
1086         if (retval != ERROR_OK)
1087         {
1088                 /* FASTDATA access failed, try normal memory write */
1089                 LOG_DEBUG("Fastdata access Failed, falling back to non-bulk write");
1090                 retval = mips_m4k_write_memory(target, address, 4, count, buffer);
1091         }
1092
1093         return retval;
1094 }
1095
1096 struct target_type mips_m4k_target =
1097 {
1098         .name = "mips_m4k",
1099
1100         .poll = mips_m4k_poll,
1101         .arch_state = mips32_arch_state,
1102
1103         .target_request_data = NULL,
1104
1105         .halt = mips_m4k_halt,
1106         .resume = mips_m4k_resume,
1107         .step = mips_m4k_step,
1108
1109         .assert_reset = mips_m4k_assert_reset,
1110         .deassert_reset = mips_m4k_deassert_reset,
1111         .soft_reset_halt = mips_m4k_soft_reset_halt,
1112
1113         .get_gdb_reg_list = mips32_get_gdb_reg_list,
1114
1115         .read_memory = mips_m4k_read_memory,
1116         .write_memory = mips_m4k_write_memory,
1117         .bulk_write_memory = mips_m4k_bulk_write_memory,
1118         .checksum_memory = mips32_checksum_memory,
1119         .blank_check_memory = mips32_blank_check_memory,
1120
1121         .run_algorithm = mips32_run_algorithm,
1122
1123         .add_breakpoint = mips_m4k_add_breakpoint,
1124         .remove_breakpoint = mips_m4k_remove_breakpoint,
1125         .add_watchpoint = mips_m4k_add_watchpoint,
1126         .remove_watchpoint = mips_m4k_remove_watchpoint,
1127
1128         .target_create = mips_m4k_target_create,
1129         .init_target = mips_m4k_init_target,
1130         .examine = mips_m4k_examine,
1131 };