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

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)