ceeed0af35624f1d243b3f3d1068eee34189692d
[fw/openocd] / src / target / nds32_v2.c
1 /***************************************************************************
2  *   Copyright (C) 2013 Andes Technology                                   *
3  *   Hsiangkai Wang <hkwang@andestech.com>                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
19  ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <helper/time_support.h>
26 #include <helper/binarybuffer.h>
27 #include "breakpoints.h"
28 #include "nds32_insn.h"
29 #include "nds32_reg.h"
30 #include "nds32_edm.h"
31 #include "nds32_cmd.h"
32 #include "nds32_v2.h"
33 #include "nds32_aice.h"
34 #include "target_type.h"
35
36 static int nds32_v2_register_mapping(struct nds32 *nds32, int reg_no)
37 {
38         uint32_t max_level = nds32->max_interrupt_level;
39         uint32_t cur_level = nds32->current_interrupt_level;
40
41         if ((1 <= cur_level) && (cur_level < max_level)) {
42                 if (IR0 == reg_no) {
43                         LOG_DEBUG("Map PSW to IPSW");
44                         return IR1;
45                 } else if (PC == reg_no) {
46                         LOG_DEBUG("Map PC to IPC");
47                         return IR9;
48                 }
49         } else if ((2 <= cur_level) && (cur_level < max_level)) {
50                 if (R26 == reg_no) {
51                         LOG_DEBUG("Mapping P0 to P_P0");
52                         return IR12;
53                 } else if (R27 == reg_no) {
54                         LOG_DEBUG("Mapping P1 to P_P1");
55                         return IR13;
56                 } else if (IR1 == reg_no) {
57                         LOG_DEBUG("Mapping IPSW to P_IPSW");
58                         return IR2;
59                 } else if (IR4 == reg_no) {
60                         LOG_DEBUG("Mapping EVA to P_EVA");
61                         return IR5;
62                 } else if (IR6 == reg_no) {
63                         LOG_DEBUG("Mapping ITYPE to P_ITYPE");
64                         return IR7;
65                 } else if (IR9 == reg_no) {
66                         LOG_DEBUG("Mapping IPC to P_IPC");
67                         return IR10;
68                 }
69         } else if (cur_level == max_level) {
70                 if (PC == reg_no) {
71                         LOG_DEBUG("Mapping PC to O_IPC");
72                         return IR11;
73                 }
74         }
75
76         return reg_no;
77 }
78
79 static int nds32_v2_get_debug_reason(struct nds32 *nds32, uint32_t *reason)
80 {
81         uint32_t val_itype;
82         struct aice_port_s *aice = target_to_aice(nds32->target);
83
84         aice_read_register(aice, IR6, &val_itype);
85
86         *reason = val_itype & 0x0F;
87
88         return ERROR_OK;
89 }
90
91 static int nds32_v2_activate_hardware_breakpoint(struct target *target)
92 {
93         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
94         struct aice_port_s *aice = target_to_aice(target);
95         struct breakpoint *bp;
96         int32_t hbr_index = 0;
97
98         for (bp = target->breakpoints; bp; bp = bp->next) {
99                 if (bp->type == BKPT_SOFT) {
100                         /* already set at nds32_v2_add_breakpoint() */
101                         continue;
102                 } else if (bp->type == BKPT_HARD) {
103                         /* set address */
104                         aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + hbr_index, bp->address);
105                         /* set mask */
106                         aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + hbr_index, 0);
107                         /* set value */
108                         aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + hbr_index, 0);
109
110                         if (nds32_v2->nds32.memory.address_translation)
111                                 /* enable breakpoint (virtual address) */
112                                 aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x2);
113                         else
114                                 /* enable breakpoint (physical address) */
115                                 aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0xA);
116
117                         LOG_DEBUG("Add hardware BP %d at %08" PRIx32, hbr_index,
118                                         bp->address);
119
120                         hbr_index++;
121                 } else {
122                         return ERROR_FAIL;
123                 }
124         }
125
126         return ERROR_OK;
127 }
128
129 static int nds32_v2_deactivate_hardware_breakpoint(struct target *target)
130 {
131         struct aice_port_s *aice = target_to_aice(target);
132         struct breakpoint *bp;
133         int32_t hbr_index = 0;
134
135         for (bp = target->breakpoints; bp; bp = bp->next) {
136                 if (bp->type == BKPT_SOFT)
137                         continue;
138                 else if (bp->type == BKPT_HARD)
139                         /* disable breakpoint */
140                         aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x0);
141                 else
142                         return ERROR_FAIL;
143
144                 LOG_DEBUG("Remove hardware BP %d at %08" PRIx32, hbr_index,
145                                 bp->address);
146
147                 hbr_index++;
148         }
149
150         return ERROR_OK;
151 }
152
153 static int nds32_v2_activate_hardware_watchpoint(struct target *target)
154 {
155         struct aice_port_s *aice = target_to_aice(target);
156         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
157         struct watchpoint *wp;
158         int32_t wp_num = nds32_v2->next_hbr_index;
159         uint32_t wp_config = 0;
160
161         for (wp = target->watchpoints; wp; wp = wp->next) {
162
163                 wp_num--;
164                 wp->mask = wp->length - 1;
165                 if ((wp->address % wp->length) != 0)
166                         wp->mask = (wp->mask << 1) + 1;
167
168                 if (wp->rw == WPT_READ)
169                         wp_config = 0x3;
170                 else if (wp->rw == WPT_WRITE)
171                         wp_config = 0x5;
172                 else if (wp->rw == WPT_ACCESS)
173                         wp_config = 0x7;
174
175                 /* set/unset physical address bit of BPCn according to PSW.DT */
176                 if (nds32_v2->nds32.memory.address_translation == false)
177                         wp_config |= 0x8;
178
179                 /* set address */
180                 aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + wp_num,
181                                 wp->address - (wp->address % wp->length));
182                 /* set mask */
183                 aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + wp_num, wp->mask);
184                 /* enable watchpoint */
185                 aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, wp_config);
186                 /* set value */
187                 aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + wp_num, 0);
188
189                 LOG_DEBUG("Add hardware wathcpoint %d at %08" PRIx32 " mask %08" PRIx32, wp_num,
190                                 wp->address, wp->mask);
191
192         }
193
194         return ERROR_OK;
195 }
196
197 static int nds32_v2_deactivate_hardware_watchpoint(struct target *target)
198 {
199         struct aice_port_s *aice = target_to_aice(target);
200         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
201         int32_t wp_num = nds32_v2->next_hbr_index;
202         struct watchpoint *wp;
203
204         for (wp = target->watchpoints; wp; wp = wp->next) {
205                 wp_num--;
206                 /* disable watchpoint */
207                 aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0);
208
209                 LOG_DEBUG("Remove hardware wathcpoint %d at %08" PRIx32 " mask %08" PRIx32,
210                                 wp_num, wp->address, wp->mask);
211         }
212
213         return ERROR_OK;
214 }
215
216 static int nds32_v2_check_interrupt_stack(struct nds32_v2_common *nds32_v2)
217 {
218         struct nds32 *nds32 = &(nds32_v2->nds32);
219         struct aice_port_s *aice = target_to_aice(nds32->target);
220         uint32_t val_ir0;
221         uint32_t val_ir1;
222         uint32_t val_ir2;
223         uint32_t modified_psw;
224
225         /* Save interrupt level */
226         aice_read_register(aice, IR0, &val_ir0); /* get $IR0 directly */
227
228         /* backup $IR0 */
229         nds32_v2->backup_ir0 = val_ir0;
230
231         nds32->current_interrupt_level = (val_ir0 >> 1) & 0x3;
232
233         if (nds32_reach_max_interrupt_level(nds32)) {
234                 LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level %d. -->",
235                                 nds32->current_interrupt_level);
236
237                 /* decrease interrupt level */
238                 modified_psw = val_ir0 - 0x2;
239
240                 /* disable GIE, IT, DT, HSS */
241                 modified_psw &= (~0x8C1);
242
243                 aice_write_register(aice, IR0, modified_psw);
244
245                 return ERROR_OK;
246         }
247
248         /* There is a case that single step also trigger another interrupt,
249            then HSS bit in psw(ir0) will push to ipsw(ir1).
250            Then hit debug interrupt HSS bit in ipsw(ir1) will push to (p_ipsw)ir2
251            Therefore, HSS bit in p_ipsw(ir2) also need clear.
252
253            Only update $ir2 as current interrupt level is 2, because $ir2 will be random
254            value if the target never reaches interrupt level 2. */
255         if ((nds32->max_interrupt_level == 3) && (nds32->current_interrupt_level == 2)) {
256                 aice_read_register(aice, IR2, &val_ir2); /* get $IR2 directly */
257                 val_ir2 &= ~(0x01 << 11);
258                 aice_write_register(aice, IR2, val_ir2);
259         }
260
261         /* get origianl DT bit and set to current state let debugger has same memory view
262            PSW.IT MUST be turned off.  Otherwise, DIM could not operate normally. */
263         aice_read_register(aice, IR1, &val_ir1);
264         modified_psw = val_ir0 | (val_ir1 & 0x80);
265         aice_write_register(aice, IR0, modified_psw);
266
267         return ERROR_OK;
268 }
269
270 static int nds32_v2_restore_interrupt_stack(struct nds32_v2_common *nds32_v2)
271 {
272         struct nds32 *nds32 = &(nds32_v2->nds32);
273         struct aice_port_s *aice = target_to_aice(nds32->target);
274
275         /* restore origin $IR0 */
276         aice_write_register(aice, IR0, nds32_v2->backup_ir0);
277
278         return ERROR_OK;
279 }
280
281 /**
282  * Save processor state.  This is called after a HALT instruction
283  * succeeds, and on other occasions the processor enters debug mode
284  * (breakpoint, watchpoint, etc).
285  */
286 static int nds32_v2_debug_entry(struct nds32 *nds32, bool enable_watchpoint)
287 {
288         LOG_DEBUG("nds32_v2_debug_entry");
289
290         jtag_poll_set_enabled(false);
291
292         if (nds32->virtual_hosting)
293                 LOG_WARNING("<-- TARGET WARNING! Virtual hosting is not supported "
294                                 "under V1/V2 architecture. -->");
295
296         enum target_state backup_state = nds32->target->state;
297         nds32->target->state = TARGET_HALTED;
298
299         if (nds32->init_arch_info_after_halted == false) {
300                 /* init architecture info according to config registers */
301                 CHECK_RETVAL(nds32_config(nds32));
302
303                 nds32->init_arch_info_after_halted = true;
304         }
305
306         /* REVISIT entire cache should already be invalid !!! */
307         register_cache_invalidate(nds32->core_cache);
308
309         /* deactivate all hardware breakpoints */
310         CHECK_RETVAL(nds32_v2_deactivate_hardware_breakpoint(nds32->target));
311
312         if (enable_watchpoint)
313                 CHECK_RETVAL(nds32_v2_deactivate_hardware_watchpoint(nds32->target));
314
315         if (ERROR_OK != nds32_examine_debug_reason(nds32)) {
316                 nds32->target->state = backup_state;
317
318                 /* re-activate all hardware breakpoints & watchpoints */
319                 CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32->target));
320
321                 if (enable_watchpoint) {
322                         /* activate all watchpoints */
323                         CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32->target));
324                 }
325
326                 return ERROR_FAIL;
327         }
328
329         /* check interrupt level before .full_context(), because
330          * get_mapped_reg() in nds32_full_context() needs current_interrupt_level
331          * information */
332         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target);
333         nds32_v2_check_interrupt_stack(nds32_v2);
334
335         /* Save registers. */
336         nds32_full_context(nds32);
337
338         return ERROR_OK;
339 }
340
341 /* target request support */
342 static int nds32_v2_target_request_data(struct target *target,
343                 uint32_t size, uint8_t *buffer)
344 {
345         /* AndesCore could use DTR register to communicate with OpenOCD
346          * to output messages
347          * Target data will be put in buffer
348          * The format of DTR is as follow
349          * DTR[31:16] => length, DTR[15:8] => size, DTR[7:0] => target_req_cmd
350          * target_req_cmd has three possible values:
351          *   TARGET_REQ_TRACEMSG
352          *   TARGET_REQ_DEBUGMSG
353          *   TARGET_REQ_DEBUGCHAR
354          * if size == 0, target will call target_asciimsg(),
355          * else call target_hexmsg()
356          */
357         LOG_WARNING("Not implemented: %s", __func__);
358
359         return ERROR_OK;
360 }
361
362 /**
363  * Restore processor state.
364  */
365 static int nds32_v2_leave_debug_state(struct nds32 *nds32, bool enable_watchpoint)
366 {
367         LOG_DEBUG("nds32_v2_leave_debug_state");
368
369         struct target *target = nds32->target;
370
371         /* activate all hardware breakpoints */
372         CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32->target));
373
374         if (enable_watchpoint) {
375                 /* activate all watchpoints */
376                 CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32->target));
377         }
378
379         /* restore interrupt stack */
380         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target);
381         nds32_v2_restore_interrupt_stack(nds32_v2);
382
383         /* restore PSW, PC, and R0 ... after flushing any modified
384          * registers.
385          */
386         CHECK_RETVAL(nds32_restore_context(target));
387
388         register_cache_invalidate(nds32->core_cache);
389
390         jtag_poll_set_enabled(true);
391
392         return ERROR_OK;
393 }
394
395 static int nds32_v2_soft_reset_halt(struct target *target)
396 {
397         /* TODO: test it */
398         struct nds32 *nds32 = target_to_nds32(target);
399         struct aice_port_s *aice = target_to_aice(target);
400
401         aice_assert_srst(aice, AICE_SRST);
402
403         /* halt core and set pc to 0x0 */
404         int retval = target_halt(target);
405         if (retval != ERROR_OK)
406                 return retval;
407
408         /* start fetching from IVB */
409         uint32_t value_ir3;
410         nds32_get_mapped_reg(nds32, IR3, &value_ir3);
411         nds32_set_mapped_reg(nds32, PC, value_ir3 & 0xFFFF0000);
412
413         return ERROR_OK;
414 }
415
416 static int nds32_v2_deassert_reset(struct target *target)
417 {
418         int retval;
419
420         CHECK_RETVAL(nds32_poll(target));
421
422         if (target->state != TARGET_HALTED) {
423                 /* reset only */
424                 LOG_WARNING("%s: ran after reset and before halt ...",
425                                 target_name(target));
426                 retval = target_halt(target);
427                 if (retval != ERROR_OK)
428                         return retval;
429                 /* call target_poll() to avoid "Halt timed out" */
430                 CHECK_RETVAL(target_poll(target));
431         } else {
432                 jtag_poll_set_enabled(false);
433         }
434
435         return ERROR_OK;
436 }
437
438 static int nds32_v2_checksum_memory(struct target *target,
439                 uint32_t address, uint32_t count, uint32_t *checksum)
440 {
441         LOG_WARNING("Not implemented: %s", __func__);
442
443         return ERROR_FAIL;
444 }
445
446 static int nds32_v2_add_breakpoint(struct target *target,
447                 struct breakpoint *breakpoint)
448 {
449         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
450         struct nds32 *nds32 = &(nds32_v2->nds32);
451         int result;
452
453         if (breakpoint->type == BKPT_HARD) {
454                 /* check hardware resource */
455                 if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) {
456                         LOG_WARNING("<-- TARGET WARNING! Insert too many hardware "
457                                         "breakpoints/watchpoints!  The limit of "
458                                         "combined hardware breakpoints/watchpoints "
459                                         "is %d. -->", nds32_v2->n_hbr);
460                         return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
461                 }
462
463                 /* update next place to put hardware breakpoint */
464                 nds32_v2->next_hbr_index++;
465
466                 /* hardware breakpoint insertion occurs before 'continue' actually */
467                 return ERROR_OK;
468         } else if (breakpoint->type == BKPT_SOFT) {
469                 result = nds32_add_software_breakpoint(target, breakpoint);
470                 if (ERROR_OK != result) {
471                         /* auto convert to hardware breakpoint if failed */
472                         if (nds32->auto_convert_hw_bp) {
473                                 /* convert to hardware breakpoint */
474                                 breakpoint->type = BKPT_HARD;
475
476                                 return nds32_v2_add_breakpoint(target, breakpoint);
477                         }
478                 }
479
480                 return result;
481         } else /* unrecognized breakpoint type */
482                 return ERROR_FAIL;
483
484         return ERROR_OK;
485 }
486
487 static int nds32_v2_remove_breakpoint(struct target *target,
488                 struct breakpoint *breakpoint)
489 {
490         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
491
492         if (breakpoint->type == BKPT_HARD) {
493                 if (nds32_v2->next_hbr_index <= 0)
494                         return ERROR_FAIL;
495
496                 /* update next place to put hardware breakpoint */
497                 nds32_v2->next_hbr_index--;
498
499                 /* hardware breakpoint removal occurs after 'halted' actually */
500                 return ERROR_OK;
501         } else if (breakpoint->type == BKPT_SOFT) {
502                 return nds32_remove_software_breakpoint(target, breakpoint);
503         } else /* unrecognized breakpoint type */
504                 return ERROR_FAIL;
505
506         return ERROR_OK;
507 }
508
509 static int nds32_v2_add_watchpoint(struct target *target,
510                 struct watchpoint *watchpoint)
511 {
512         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
513
514         /* check hardware resource */
515         if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) {
516                 LOG_WARNING("<-- TARGET WARNING! Insert too many hardware "
517                                 "breakpoints/watchpoints!  The limit of "
518                                 "combined hardware breakpoints/watchpoints is %d. -->", nds32_v2->n_hbr);
519                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
520         }
521
522         /* update next place to put hardware watchpoint */
523         nds32_v2->next_hbr_index++;
524
525         return ERROR_OK;
526 }
527
528 static int nds32_v2_remove_watchpoint(struct target *target,
529                 struct watchpoint *watchpoint)
530 {
531         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
532
533         if (nds32_v2->next_hbr_index <= 0)
534                 return ERROR_FAIL;
535
536         /* update next place to put hardware breakpoint */
537         nds32_v2->next_hbr_index--;
538
539         return ERROR_OK;
540 }
541
542 static int nds32_v2_get_exception_address(struct nds32 *nds32,
543                 uint32_t *address, uint32_t reason)
544 {
545         struct aice_port_s *aice = target_to_aice(nds32->target);
546
547         aice_read_register(aice, IR4, address); /* read $EVA directly */
548
549         /* TODO: hit multiple watchpoints */
550
551         return ERROR_OK;
552 }
553
554 /**
555  * find out which watchpoint hits
556  * get exception address and compare the address to watchpoints
557  */
558 static int nds32_v2_hit_watchpoint(struct target *target,
559                 struct watchpoint **hit_watchpoint)
560 {
561         uint32_t exception_address;
562         struct watchpoint *wp;
563         static struct watchpoint scan_all_watchpoint;
564         struct nds32 *nds32 = target_to_nds32(target);
565
566         scan_all_watchpoint.address = 0;
567         scan_all_watchpoint.rw = WPT_WRITE;
568         scan_all_watchpoint.next = 0;
569         scan_all_watchpoint.unique_id = 0x5CA8;
570
571         exception_address = nds32->watched_address;
572
573         if (exception_address == 0) {
574                 /* send watch:0 to tell GDB to do software scan for hitting multiple watchpoints */
575                 *hit_watchpoint = &scan_all_watchpoint;
576                 return ERROR_OK;
577         }
578
579         for (wp = target->watchpoints; wp; wp = wp->next) {
580                 if (((exception_address ^ wp->address) & (~wp->mask)) == 0) {
581                         /* TODO: dispel false match */
582                         *hit_watchpoint = wp;
583                         return ERROR_OK;
584                 }
585         }
586
587         return ERROR_FAIL;
588 }
589
590 static int nds32_v2_run_algorithm(struct target *target,
591                 int num_mem_params,
592                 struct mem_param *mem_params,
593                 int num_reg_params,
594                 struct reg_param *reg_params,
595                 uint32_t entry_point,
596                 uint32_t exit_point,
597                 int timeout_ms,
598                 void *arch_info)
599 {
600         LOG_WARNING("Not implemented: %s", __func__);
601
602         return ERROR_FAIL;
603 }
604
605 static int nds32_v2_target_create(struct target *target, Jim_Interp *interp)
606 {
607         struct nds32_v2_common *nds32_v2;
608
609         nds32_v2 = calloc(1, sizeof(*nds32_v2));
610         if (!nds32_v2)
611                 return ERROR_FAIL;
612
613         nds32_v2->nds32.register_map = nds32_v2_register_mapping;
614         nds32_v2->nds32.get_debug_reason = nds32_v2_get_debug_reason;
615         nds32_v2->nds32.enter_debug_state = nds32_v2_debug_entry;
616         nds32_v2->nds32.leave_debug_state = nds32_v2_leave_debug_state;
617         nds32_v2->nds32.get_watched_address = nds32_v2_get_exception_address;
618
619         nds32_init_arch_info(target, &(nds32_v2->nds32));
620
621         return ERROR_OK;
622 }
623
624 static int nds32_v2_init_target(struct command_context *cmd_ctx,
625                 struct target *target)
626 {
627         /* Initialize anything we can set up without talking to the target */
628
629         struct nds32 *nds32 = target_to_nds32(target);
630
631         nds32_init(nds32);
632
633         return ERROR_OK;
634 }
635
636 /* talk to the target and set things up */
637 static int nds32_v2_examine(struct target *target)
638 {
639         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
640         struct nds32 *nds32 = &(nds32_v2->nds32);
641         struct aice_port_s *aice = target_to_aice(target);
642
643         if (!target_was_examined(target)) {
644                 CHECK_RETVAL(nds32_edm_config(nds32));
645
646                 if (nds32->reset_halt_as_examine)
647                         CHECK_RETVAL(nds32_reset_halt(nds32));
648         }
649
650         uint32_t edm_cfg;
651         aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg);
652
653         /* get the number of hardware breakpoints */
654         nds32_v2->n_hbr = (edm_cfg & 0x7) + 1;
655
656         nds32_v2->next_hbr_index = 0;
657
658         LOG_INFO("%s: total hardware breakpoint %d", target_name(target),
659                         nds32_v2->n_hbr);
660
661         nds32->target->state = TARGET_RUNNING;
662         nds32->target->debug_reason = DBG_REASON_NOTHALTED;
663
664         target_set_examined(target);
665
666         return ERROR_OK;
667 }
668
669 static int nds32_v2_translate_address(struct target *target, uint32_t *address)
670 {
671         struct nds32 *nds32 = target_to_nds32(target);
672         struct nds32_memory *memory = &(nds32->memory);
673         uint32_t physical_address;
674
675         /* Following conditions need to do address translation
676          * 1. BUS mode
677          * 2. CPU mode under maximum interrupt level */
678         if ((NDS_MEMORY_ACC_BUS == memory->access_channel) ||
679                         ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
680                          nds32_reach_max_interrupt_level(nds32))) {
681                 if (ERROR_OK == target->type->virt2phys(target, *address, &physical_address))
682                         *address = physical_address;
683                 else
684                         return ERROR_FAIL;
685         }
686
687         return ERROR_OK;
688 }
689
690 static int nds32_v2_read_buffer(struct target *target, uint32_t address,
691                 uint32_t size, uint8_t *buffer)
692 {
693         struct nds32 *nds32 = target_to_nds32(target);
694         struct nds32_memory *memory = &(nds32->memory);
695
696         if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
697                         (target->state != TARGET_HALTED)) {
698                 LOG_WARNING("target was not halted");
699                 return ERROR_TARGET_NOT_HALTED;
700         }
701
702         /* BUG: If access range crosses multiple pages, the translation will not correct
703          * for second page or so. */
704
705         nds32_v2_translate_address(target, &address);
706
707         return nds32_read_buffer(target, address, size, buffer);
708 }
709
710 static int nds32_v2_write_buffer(struct target *target, uint32_t address,
711                 uint32_t size, const uint8_t *buffer)
712 {
713         struct nds32 *nds32 = target_to_nds32(target);
714         struct nds32_memory *memory = &(nds32->memory);
715
716         if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
717                         (target->state != TARGET_HALTED)) {
718                 LOG_WARNING("target was not halted");
719                 return ERROR_TARGET_NOT_HALTED;
720         }
721
722         /* BUG: If access range crosses multiple pages, the translation will not correct
723          * for second page or so. */
724
725         nds32_v2_translate_address(target, &address);
726
727         return nds32_write_buffer(target, address, size, buffer);
728 }
729
730 static int nds32_v2_read_memory(struct target *target, uint32_t address,
731                 uint32_t size, uint32_t count, uint8_t *buffer)
732 {
733         struct nds32 *nds32 = target_to_nds32(target);
734         struct nds32_memory *memory = &(nds32->memory);
735
736         if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
737                         (target->state != TARGET_HALTED)) {
738                 LOG_WARNING("target was not halted");
739                 return ERROR_TARGET_NOT_HALTED;
740         }
741
742         /* BUG: If access range crosses multiple pages, the translation will not correct
743          * for second page or so. */
744
745         nds32_v2_translate_address(target, &address);
746
747         return nds32_read_memory(target, address, size, count, buffer);
748 }
749
750 static int nds32_v2_write_memory(struct target *target, uint32_t address,
751                 uint32_t size, uint32_t count, const uint8_t *buffer)
752 {
753         struct nds32 *nds32 = target_to_nds32(target);
754         struct nds32_memory *memory = &(nds32->memory);
755
756         if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
757                         (target->state != TARGET_HALTED)) {
758                 LOG_WARNING("target was not halted");
759                 return ERROR_TARGET_NOT_HALTED;
760         }
761
762         /* BUG: If access range crosses multiple pages, the translation will not correct
763          * for second page or so. */
764
765         nds32_v2_translate_address(target, &address);
766
767         return nds32_write_memory(target, address, size, count, buffer);
768 }
769
770 /** Holds methods for V2 targets. */
771 struct target_type nds32_v2_target = {
772         .name = "nds32_v2",
773
774         .poll = nds32_poll,
775         .arch_state = nds32_arch_state,
776
777         .target_request_data = nds32_v2_target_request_data,
778
779         .halt = nds32_halt,
780         .resume = nds32_resume,
781         .step = nds32_step,
782
783         .assert_reset = nds32_assert_reset,
784         .deassert_reset = nds32_v2_deassert_reset,
785         .soft_reset_halt = nds32_v2_soft_reset_halt,
786
787         /* register access */
788         .get_gdb_reg_list = nds32_get_gdb_reg_list,
789
790         /* memory access */
791         .read_buffer = nds32_v2_read_buffer,
792         .write_buffer = nds32_v2_write_buffer,
793         .read_memory = nds32_v2_read_memory,
794         .write_memory = nds32_v2_write_memory,
795
796         .checksum_memory = nds32_v2_checksum_memory,
797
798         /* breakpoint/watchpoint */
799         .add_breakpoint = nds32_v2_add_breakpoint,
800         .remove_breakpoint = nds32_v2_remove_breakpoint,
801         .add_watchpoint = nds32_v2_add_watchpoint,
802         .remove_watchpoint = nds32_v2_remove_watchpoint,
803         .hit_watchpoint = nds32_v2_hit_watchpoint,
804
805         /* MMU */
806         .mmu = nds32_mmu,
807         .virt2phys = nds32_virtual_to_physical,
808         .read_phys_memory = nds32_read_phys_memory,
809         .write_phys_memory = nds32_write_phys_memory,
810
811         .run_algorithm = nds32_v2_run_algorithm,
812
813         .commands = nds32_command_handlers,
814         .target_create = nds32_v2_target_create,
815         .init_target = nds32_v2_init_target,
816         .examine = nds32_v2_examine,
817 };