]> git.gag.com Git - fw/openocd/blob - src/target/nds32_v2.c
gdb server: new feature, add stop reason in stop reply packet for gdb
[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
249         /* There is a case that single step also trigger another interrupt,
250            then HSS bit in psw(ir0) will push to ipsw(ir1).
251            Then hit debug interrupt HSS bit in ipsw(ir1) will push to (p_ipsw)ir2
252            Therefore, HSS bit in p_ipsw(ir2) also need clear.
253
254            Only update $ir2 as current interrupt level is 2, because $ir2 will be random
255            value if the target never reaches interrupt level 2. */
256         if ((nds32->max_interrupt_level == 3) && (nds32->current_interrupt_level == 2)) {
257                 aice_read_register(aice, IR2, &val_ir2); /* get $IR2 directly */
258                 val_ir2 &= ~(0x01 << 11);
259                 aice_write_register(aice, IR2, val_ir2);
260         }
261
262         /* get origianl DT bit and set to current state let debugger has same memory view
263            PSW.IT MUST be turned off.  Otherwise, DIM could not operate normally. */
264         aice_read_register(aice, IR1, &val_ir1);
265         modified_psw = val_ir0 | (val_ir1 & 0x80);
266         aice_write_register(aice, IR0, modified_psw);
267
268         return ERROR_OK;
269 }
270
271 static int nds32_v2_restore_interrupt_stack(struct nds32_v2_common *nds32_v2)
272 {
273         struct nds32 *nds32 = &(nds32_v2->nds32);
274         struct aice_port_s *aice = target_to_aice(nds32->target);
275
276         /* restore origin $IR0 */
277         aice_write_register(aice, IR0, nds32_v2->backup_ir0);
278
279         return ERROR_OK;
280 }
281
282 /**
283  * Save processor state.  This is called after a HALT instruction
284  * succeeds, and on other occasions the processor enters debug mode
285  * (breakpoint, watchpoint, etc).
286  */
287 static int nds32_v2_debug_entry(struct nds32 *nds32, bool enable_watchpoint)
288 {
289         LOG_DEBUG("nds32_v2_debug_entry");
290
291         jtag_poll_set_enabled(false);
292
293         if (nds32->virtual_hosting)
294                 LOG_WARNING("<-- TARGET WARNING! Virtual hosting is not supported "
295                                 "under V1/V2 architecture. -->");
296
297         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target);
298
299         CHECK_RETVAL(nds32_v2_deactivate_hardware_breakpoint(nds32->target));
300
301         if (enable_watchpoint)
302                 CHECK_RETVAL(nds32_v2_deactivate_hardware_watchpoint(nds32->target));
303
304         nds32->target->state = TARGET_HALTED;
305         nds32_examine_debug_reason(nds32);
306
307         if (nds32->init_arch_info_after_halted == false) {
308                 /* init architecture info according to config registers */
309                 CHECK_RETVAL(nds32_config(nds32));
310
311                 nds32->init_arch_info_after_halted = true;
312         }
313
314         /* REVISIT entire cache should already be invalid !!! */
315         register_cache_invalidate(nds32->core_cache);
316
317         /* check interrupt level before .full_context(), because
318          * get_mapped_reg needs current_interrupt_level information */
319         nds32_v2_check_interrupt_stack(nds32_v2);
320
321         /* Save registers. */
322         nds32_full_context(nds32);
323
324         return ERROR_OK;
325 }
326
327 /* target request support */
328 static int nds32_v2_target_request_data(struct target *target,
329                 uint32_t size, uint8_t *buffer)
330 {
331         /* AndesCore could use DTR register to communicate with OpenOCD
332          * to output messages
333          * Target data will be put in buffer
334          * The format of DTR is as follow
335          * DTR[31:16] => length, DTR[15:8] => size, DTR[7:0] => target_req_cmd
336          * target_req_cmd has three possible values:
337          *   TARGET_REQ_TRACEMSG
338          *   TARGET_REQ_DEBUGMSG
339          *   TARGET_REQ_DEBUGCHAR
340          * if size == 0, target will call target_asciimsg(),
341          * else call target_hexmsg()
342          */
343         LOG_WARNING("Not implemented: %s", __func__);
344
345         return ERROR_OK;
346 }
347
348 /**
349  * Restore processor state.
350  */
351 static int nds32_v2_leave_debug_state(struct nds32 *nds32, bool enable_watchpoint)
352 {
353         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target);
354
355         /* activate all hardware breakpoints */
356         CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32->target));
357
358         if (enable_watchpoint) {
359                 /* activate all watchpoints */
360                 CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32->target));
361         }
362
363         /* restore interrupt stack */
364         nds32_v2_restore_interrupt_stack(nds32_v2);
365
366         /* restore PSW, PC, and R0 ... after flushing any modified
367          * registers.
368          */
369         CHECK_RETVAL(nds32_restore_context(nds32->target));
370
371         register_cache_invalidate(nds32->core_cache);
372
373         jtag_poll_set_enabled(true);
374
375         return ERROR_OK;
376 }
377
378 static int nds32_v2_soft_reset_halt(struct target *target)
379 {
380         /* TODO: test it */
381         struct nds32 *nds32 = target_to_nds32(target);
382         struct aice_port_s *aice = target_to_aice(target);
383
384         aice_assert_srst(aice, AICE_SRST);
385
386         /* halt core and set pc to 0x0 */
387         int retval = target_halt(target);
388         if (retval != ERROR_OK)
389                 return retval;
390
391         /* start fetching from IVB */
392         uint32_t value_ir3;
393         nds32_get_mapped_reg(nds32, IR3, &value_ir3);
394         nds32_set_mapped_reg(nds32, PC, value_ir3 & 0xFFFF0000);
395
396         return ERROR_OK;
397 }
398
399 static int nds32_v2_deassert_reset(struct target *target)
400 {
401         int retval;
402
403         CHECK_RETVAL(nds32_poll(target));
404
405         if (target->state != TARGET_HALTED) {
406                 /* reset only */
407                 LOG_WARNING("%s: ran after reset and before halt ...",
408                                 target_name(target));
409                 retval = target_halt(target);
410                 if (retval != ERROR_OK)
411                         return retval;
412                 /* call target_poll() to avoid "Halt timed out" */
413                 CHECK_RETVAL(target_poll(target));
414         } else {
415                 jtag_poll_set_enabled(false);
416         }
417
418         return ERROR_OK;
419 }
420
421 static int nds32_v2_checksum_memory(struct target *target,
422                 uint32_t address, uint32_t count, uint32_t *checksum)
423 {
424         LOG_WARNING("Not implemented: %s", __func__);
425
426         return ERROR_FAIL;
427 }
428
429 static int nds32_v2_add_breakpoint(struct target *target,
430                 struct breakpoint *breakpoint)
431 {
432         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
433         struct nds32 *nds32 = &(nds32_v2->nds32);
434         int result;
435
436         if (breakpoint->type == BKPT_HARD) {
437                 /* check hardware resource */
438                 if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) {
439                         LOG_WARNING("<-- TARGET WARNING! Insert too many hardware "
440                                         "breakpoints/watchpoints!  The limit of "
441                                         "combined hardware breakpoints/watchpoints "
442                                         "is %d. -->", nds32_v2->n_hbr);
443                         return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
444                 }
445
446                 /* update next place to put hardware breakpoint */
447                 nds32_v2->next_hbr_index++;
448
449                 /* hardware breakpoint insertion occurs before 'continue' actually */
450                 return ERROR_OK;
451         } else if (breakpoint->type == BKPT_SOFT) {
452                 result = nds32_add_software_breakpoint(target, breakpoint);
453                 if (ERROR_OK != result) {
454                         /* auto convert to hardware breakpoint if failed */
455                         if (nds32->auto_convert_hw_bp) {
456                                 /* convert to hardware breakpoint */
457                                 breakpoint->type = BKPT_HARD;
458
459                                 return nds32_v2_add_breakpoint(target, breakpoint);
460                         }
461                 }
462
463                 return result;
464         } else /* unrecognized breakpoint type */
465                 return ERROR_FAIL;
466
467         return ERROR_OK;
468 }
469
470 static int nds32_v2_remove_breakpoint(struct target *target,
471                 struct breakpoint *breakpoint)
472 {
473         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
474
475         if (breakpoint->type == BKPT_HARD) {
476                 if (nds32_v2->next_hbr_index <= 0)
477                         return ERROR_FAIL;
478
479                 /* update next place to put hardware breakpoint */
480                 nds32_v2->next_hbr_index--;
481
482                 /* hardware breakpoint removal occurs after 'halted' actually */
483                 return ERROR_OK;
484         } else if (breakpoint->type == BKPT_SOFT) {
485                 return nds32_remove_software_breakpoint(target, breakpoint);
486         } else /* unrecognized breakpoint type */
487                 return ERROR_FAIL;
488
489         return ERROR_OK;
490 }
491
492 static int nds32_v2_add_watchpoint(struct target *target,
493                 struct watchpoint *watchpoint)
494 {
495         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
496
497         /* check hardware resource */
498         if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) {
499                 LOG_WARNING("<-- TARGET WARNING! Insert too many hardware "
500                                 "breakpoints/watchpoints!  The limit of "
501                                 "combined hardware breakpoints/watchpoints is %d. -->", nds32_v2->n_hbr);
502                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
503         }
504
505         /* update next place to put hardware watchpoint */
506         nds32_v2->next_hbr_index++;
507
508         return ERROR_OK;
509 }
510
511 static int nds32_v2_remove_watchpoint(struct target *target,
512                 struct watchpoint *watchpoint)
513 {
514         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
515
516         if (nds32_v2->next_hbr_index <= 0)
517                 return ERROR_FAIL;
518
519         /* update next place to put hardware breakpoint */
520         nds32_v2->next_hbr_index--;
521
522         return ERROR_OK;
523 }
524
525 static int nds32_v2_get_exception_address(struct nds32 *nds32,
526                 uint32_t *address, uint32_t reason)
527 {
528         struct aice_port_s *aice = target_to_aice(nds32->target);
529
530         aice_read_register(aice, IR4, address); /* read $EVA directly */
531
532         /* TODO: hit multiple watchpoints */
533
534         return ERROR_OK;
535 }
536
537 /**
538  * find out which watchpoint hits
539  * get exception address and compare the address to watchpoints
540  */
541 static int nds32_v2_hit_watchpoint(struct target *target,
542                 struct watchpoint **hit_watchpoint)
543 {
544         uint32_t exception_address;
545         struct watchpoint *wp;
546         static struct watchpoint scan_all_watchpoint;
547         struct nds32 *nds32 = target_to_nds32(target);
548
549         scan_all_watchpoint.address = 0;
550         scan_all_watchpoint.rw = WPT_WRITE;
551         scan_all_watchpoint.next = 0;
552         scan_all_watchpoint.unique_id = 0x5CA8;
553
554         exception_address = nds32->watched_address;
555
556         if (exception_address == 0) {
557                 /* send watch:0 to tell GDB to do software scan for hitting multiple watchpoints */
558                 *hit_watchpoint = &scan_all_watchpoint;
559                 return ERROR_OK;
560         }
561
562         for (wp = target->watchpoints; wp; wp = wp->next) {
563                 if (((exception_address ^ wp->address) & (~wp->mask)) == 0) {
564                         /* TODO: dispel false match */
565                         *hit_watchpoint = wp;
566                         return ERROR_OK;
567                 }
568         }
569
570         return ERROR_FAIL;
571 }
572
573 static int nds32_v2_run_algorithm(struct target *target,
574                 int num_mem_params,
575                 struct mem_param *mem_params,
576                 int num_reg_params,
577                 struct reg_param *reg_params,
578                 uint32_t entry_point,
579                 uint32_t exit_point,
580                 int timeout_ms,
581                 void *arch_info)
582 {
583         LOG_WARNING("Not implemented: %s", __func__);
584
585         return ERROR_FAIL;
586 }
587
588 static int nds32_v2_target_create(struct target *target, Jim_Interp *interp)
589 {
590         struct nds32_v2_common *nds32_v2;
591
592         nds32_v2 = calloc(1, sizeof(*nds32_v2));
593         if (!nds32_v2)
594                 return ERROR_FAIL;
595
596         nds32_v2->nds32.register_map = nds32_v2_register_mapping;
597         nds32_v2->nds32.get_debug_reason = nds32_v2_get_debug_reason;
598         nds32_v2->nds32.enter_debug_state = nds32_v2_debug_entry;
599         nds32_v2->nds32.leave_debug_state = nds32_v2_leave_debug_state;
600         nds32_v2->nds32.get_watched_address = nds32_v2_get_exception_address;
601
602         nds32_init_arch_info(target, &(nds32_v2->nds32));
603
604         return ERROR_OK;
605 }
606
607 static int nds32_v2_init_target(struct command_context *cmd_ctx,
608                 struct target *target)
609 {
610         /* Initialize anything we can set up without talking to the target */
611
612         struct nds32 *nds32 = target_to_nds32(target);
613
614         nds32_init(nds32);
615
616         return ERROR_OK;
617 }
618
619 /* talk to the target and set things up */
620 static int nds32_v2_examine(struct target *target)
621 {
622         struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target);
623         struct nds32 *nds32 = &(nds32_v2->nds32);
624         struct aice_port_s *aice = target_to_aice(target);
625
626         if (!target_was_examined(target)) {
627                 CHECK_RETVAL(nds32_edm_config(nds32));
628
629                 if (nds32->reset_halt_as_examine)
630                         CHECK_RETVAL(nds32_reset_halt(nds32));
631         }
632
633         uint32_t edm_cfg;
634         aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg);
635
636         /* get the number of hardware breakpoints */
637         nds32_v2->n_hbr = (edm_cfg & 0x7) + 1;
638
639         nds32_v2->next_hbr_index = 0;
640
641         LOG_INFO("%s: total hardware breakpoint %d", target_name(target),
642                         nds32_v2->n_hbr);
643
644         nds32->target->state = TARGET_RUNNING;
645         nds32->target->debug_reason = DBG_REASON_NOTHALTED;
646
647         target_set_examined(target);
648
649         return ERROR_OK;
650 }
651
652 static int nds32_v2_translate_address(struct target *target, uint32_t *address)
653 {
654         struct nds32 *nds32 = target_to_nds32(target);
655         struct nds32_memory *memory = &(nds32->memory);
656         uint32_t physical_address;
657
658         /* Following conditions need to do address translation
659          * 1. BUS mode
660          * 2. CPU mode under maximum interrupt level */
661         if ((NDS_MEMORY_ACC_BUS == memory->access_channel) ||
662                         ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
663                          nds32_reach_max_interrupt_level(nds32))) {
664                 if (ERROR_OK == target->type->virt2phys(target, *address, &physical_address))
665                         *address = physical_address;
666                 else
667                         return ERROR_FAIL;
668         }
669
670         return ERROR_OK;
671 }
672
673 static int nds32_v2_read_buffer(struct target *target, uint32_t address,
674                 uint32_t size, uint8_t *buffer)
675 {
676         struct nds32 *nds32 = target_to_nds32(target);
677         struct nds32_memory *memory = &(nds32->memory);
678
679         if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
680                         (target->state != TARGET_HALTED)) {
681                 LOG_WARNING("target was not halted");
682                 return ERROR_TARGET_NOT_HALTED;
683         }
684
685         /* BUG: If access range crosses multiple pages, the translation will not correct
686          * for second page or so. */
687
688         nds32_v2_translate_address(target, &address);
689
690         return nds32_read_buffer(target, address, size, buffer);
691 }
692
693 static int nds32_v2_write_buffer(struct target *target, uint32_t address,
694                 uint32_t size, const uint8_t *buffer)
695 {
696         struct nds32 *nds32 = target_to_nds32(target);
697         struct nds32_memory *memory = &(nds32->memory);
698
699         if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
700                         (target->state != TARGET_HALTED)) {
701                 LOG_WARNING("target was not halted");
702                 return ERROR_TARGET_NOT_HALTED;
703         }
704
705         /* BUG: If access range crosses multiple pages, the translation will not correct
706          * for second page or so. */
707
708         nds32_v2_translate_address(target, &address);
709
710         return nds32_write_buffer(target, address, size, buffer);
711 }
712
713 static int nds32_v2_read_memory(struct target *target, uint32_t address,
714                 uint32_t size, uint32_t count, uint8_t *buffer)
715 {
716         struct nds32 *nds32 = target_to_nds32(target);
717         struct nds32_memory *memory = &(nds32->memory);
718
719         if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
720                         (target->state != TARGET_HALTED)) {
721                 LOG_WARNING("target was not halted");
722                 return ERROR_TARGET_NOT_HALTED;
723         }
724
725         /* BUG: If access range crosses multiple pages, the translation will not correct
726          * for second page or so. */
727
728         nds32_v2_translate_address(target, &address);
729
730         return nds32_read_memory(target, address, size, count, buffer);
731 }
732
733 static int nds32_v2_write_memory(struct target *target, uint32_t address,
734                 uint32_t size, uint32_t count, const uint8_t *buffer)
735 {
736         struct nds32 *nds32 = target_to_nds32(target);
737         struct nds32_memory *memory = &(nds32->memory);
738
739         if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
740                         (target->state != TARGET_HALTED)) {
741                 LOG_WARNING("target was not halted");
742                 return ERROR_TARGET_NOT_HALTED;
743         }
744
745         /* BUG: If access range crosses multiple pages, the translation will not correct
746          * for second page or so. */
747
748         nds32_v2_translate_address(target, &address);
749
750         return nds32_write_memory(target, address, size, count, buffer);
751 }
752
753 /** Holds methods for V2 targets. */
754 struct target_type nds32_v2_target = {
755         .name = "nds32_v2",
756
757         .poll = nds32_poll,
758         .arch_state = nds32_arch_state,
759
760         .target_request_data = nds32_v2_target_request_data,
761
762         .halt = nds32_halt,
763         .resume = nds32_resume,
764         .step = nds32_step,
765
766         .assert_reset = nds32_assert_reset,
767         .deassert_reset = nds32_v2_deassert_reset,
768         .soft_reset_halt = nds32_v2_soft_reset_halt,
769
770         /* register access */
771         .get_gdb_reg_list = nds32_get_gdb_reg_list,
772
773         /* memory access */
774         .read_buffer = nds32_v2_read_buffer,
775         .write_buffer = nds32_v2_write_buffer,
776         .read_memory = nds32_v2_read_memory,
777         .write_memory = nds32_v2_write_memory,
778
779         .checksum_memory = nds32_v2_checksum_memory,
780
781         /* breakpoint/watchpoint */
782         .add_breakpoint = nds32_v2_add_breakpoint,
783         .remove_breakpoint = nds32_v2_remove_breakpoint,
784         .add_watchpoint = nds32_v2_add_watchpoint,
785         .remove_watchpoint = nds32_v2_remove_watchpoint,
786         .hit_watchpoint = nds32_v2_hit_watchpoint,
787
788         /* MMU */
789         .mmu = nds32_mmu,
790         .virt2phys = nds32_virtual_to_physical,
791         .read_phys_memory = nds32_read_phys_memory,
792         .write_phys_memory = nds32_write_phys_memory,
793
794         .run_algorithm = nds32_v2_run_algorithm,
795
796         .commands = nds32_command_handlers,
797         .target_create = nds32_v2_target_create,
798         .init_target = nds32_v2_init_target,
799         .examine = nds32_v2_examine,
800 };