nds32: Use DMA to access memory as no DCache
[openocd.git] / src / target / nds32_v3_common.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 "breakpoints.h"
26 #include "nds32_reg.h"
27 #include "nds32_disassembler.h"
28 #include "nds32.h"
29 #include "nds32_aice.h"
30 #include "nds32_v3_common.h"
31
32 static struct breakpoint syscall_breakpoint = {
33 0x80,
34 0,
35 4,
36 BKPT_SOFT,
37 0,
38 NULL,
39 NULL,
40 0x515CA11,
41 0,
42 };
43
44 static struct nds32_v3_common_callback *v3_common_callback;
45
46 static int nds32_v3_register_mapping(struct nds32 *nds32, int reg_no)
47 {
48 if (reg_no == PC)
49 return IR11;
50
51 return reg_no;
52 }
53
54 static int nds32_v3_get_debug_reason(struct nds32 *nds32, uint32_t *reason)
55 {
56 uint32_t edmsw;
57 struct aice_port_s *aice = target_to_aice(nds32->target);
58 aice_read_debug_reg(aice, NDS_EDM_SR_EDMSW, &edmsw);
59
60 *reason = (edmsw >> 12) & 0x0F;
61
62 return ERROR_OK;
63 }
64
65 /**
66 * Save processor state. This is called after a HALT instruction
67 * succeeds, and on other occasions the processor enters debug mode
68 * (breakpoint, watchpoint, etc).
69 */
70 static int nds32_v3_debug_entry(struct nds32 *nds32, bool enable_watchpoint)
71 {
72 LOG_DEBUG("nds32_v3_debug_entry");
73
74 enum target_state backup_state = nds32->target->state;
75 nds32->target->state = TARGET_HALTED;
76
77 if (nds32->init_arch_info_after_halted == false) {
78 /* init architecture info according to config registers */
79 CHECK_RETVAL(nds32_config(nds32));
80
81 nds32->init_arch_info_after_halted = true;
82 }
83
84 /* REVISIT entire cache should already be invalid !!! */
85 register_cache_invalidate(nds32->core_cache);
86
87 /* deactivate all hardware breakpoints */
88 CHECK_RETVAL(v3_common_callback->deactivate_hardware_breakpoint(nds32->target));
89
90 if (enable_watchpoint)
91 CHECK_RETVAL(v3_common_callback->deactivate_hardware_watchpoint(nds32->target));
92
93 if (nds32->virtual_hosting) {
94 if (syscall_breakpoint.set) {
95 /** disable virtual hosting */
96
97 /* remove breakpoint at syscall entry */
98 target_remove_breakpoint(nds32->target, &syscall_breakpoint);
99 syscall_breakpoint.set = 0;
100
101 uint32_t value_pc;
102 nds32_get_mapped_reg(nds32, PC, &value_pc);
103 if (value_pc == syscall_breakpoint.address)
104 /** process syscall for virtual hosting */
105 nds32->hit_syscall = true;
106 }
107 }
108
109 if (ERROR_OK != nds32_examine_debug_reason(nds32)) {
110 nds32->target->state = backup_state;
111
112 /* re-activate all hardware breakpoints & watchpoints */
113 CHECK_RETVAL(v3_common_callback->activate_hardware_breakpoint(nds32->target));
114
115 if (enable_watchpoint)
116 CHECK_RETVAL(v3_common_callback->activate_hardware_watchpoint(nds32->target));
117
118 return ERROR_FAIL;
119 }
120
121 /* Save registers. */
122 nds32_full_context(nds32);
123
124 /* check interrupt level */
125 v3_common_callback->check_interrupt_stack(nds32);
126
127 return ERROR_OK;
128 }
129
130 /**
131 * Restore processor state.
132 */
133 static int nds32_v3_leave_debug_state(struct nds32 *nds32, bool enable_watchpoint)
134 {
135 LOG_DEBUG("nds32_v3_leave_debug_state");
136
137 struct target *target = nds32->target;
138
139 /* activate all hardware breakpoints */
140 CHECK_RETVAL(v3_common_callback->activate_hardware_breakpoint(target));
141
142 if (enable_watchpoint) {
143 /* activate all watchpoints */
144 CHECK_RETVAL(v3_common_callback->activate_hardware_watchpoint(target));
145 }
146
147 /* restore interrupt stack */
148 v3_common_callback->restore_interrupt_stack(nds32);
149
150 /* REVISIT once we start caring about MMU and cache state,
151 * address it here ...
152 */
153
154 /* restore PSW, PC, and R0 ... after flushing any modified
155 * registers.
156 */
157 CHECK_RETVAL(nds32_restore_context(target));
158
159 if (nds32->virtual_hosting) {
160 /** enable virtual hosting */
161 uint32_t value_ir3;
162 uint32_t entry_size;
163 uint32_t syscall_address;
164
165 /* get syscall entry address */
166 nds32_get_mapped_reg(nds32, IR3, &value_ir3);
167 entry_size = 0x4 << (((value_ir3 >> 14) & 0x3) << 1);
168 syscall_address = (value_ir3 & 0xFFFF0000) + entry_size * 8; /* The index of SYSCALL is 8 */
169
170 if (nds32->hit_syscall) {
171 /* single step to skip syscall entry */
172 /* use IRET to skip syscall */
173 struct aice_port_s *aice = target_to_aice(target);
174 uint32_t value_ir9;
175 uint32_t value_ir6;
176 uint32_t syscall_id;
177
178 nds32_get_mapped_reg(nds32, IR6, &value_ir6);
179 syscall_id = (value_ir6 >> 16) & 0x7FFF;
180
181 if (syscall_id == NDS32_SYSCALL_EXIT) {
182 /* If target hits exit syscall, do not use IRET to skip handler. */
183 aice_step(aice);
184 } else {
185 /* use api->read/write_reg to skip nds32 register cache */
186 uint32_t value_dimbr;
187 aice_read_debug_reg(aice, NDS_EDM_SR_DIMBR, &value_dimbr);
188 aice_write_register(aice, IR11, value_dimbr + 0xC);
189
190 aice_read_register(aice, IR9, &value_ir9);
191 value_ir9 += 4; /* syscall is always 4 bytes */
192 aice_write_register(aice, IR9, value_ir9);
193
194 /* backup hardware breakpoint 0 */
195 uint32_t backup_bpa, backup_bpam, backup_bpc;
196 aice_read_debug_reg(aice, NDS_EDM_SR_BPA0, &backup_bpa);
197 aice_read_debug_reg(aice, NDS_EDM_SR_BPAM0, &backup_bpam);
198 aice_read_debug_reg(aice, NDS_EDM_SR_BPC0, &backup_bpc);
199
200 /* use hardware breakpoint 0 to stop cpu after skipping syscall */
201 aice_write_debug_reg(aice, NDS_EDM_SR_BPA0, value_ir9);
202 aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0, 0);
203 aice_write_debug_reg(aice, NDS_EDM_SR_BPC0, 0xA);
204
205 /* Execute two IRET.
206 * First IRET is used to quit debug mode.
207 * Second IRET is used to quit current syscall. */
208 uint32_t dim_inst[4] = {NOP, NOP, IRET, IRET};
209 aice_execute(aice, dim_inst, 4);
210
211 /* restore origin hardware breakpoint 0 */
212 aice_write_debug_reg(aice, NDS_EDM_SR_BPA0, backup_bpa);
213 aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0, backup_bpam);
214 aice_write_debug_reg(aice, NDS_EDM_SR_BPC0, backup_bpc);
215 }
216
217 nds32->hit_syscall = false;
218 }
219
220 /* insert breakpoint at syscall entry */
221 syscall_breakpoint.address = syscall_address;
222 syscall_breakpoint.type = BKPT_SOFT;
223 syscall_breakpoint.set = 1;
224 target_add_breakpoint(target, &syscall_breakpoint);
225 }
226
227 return ERROR_OK;
228 }
229
230 static int nds32_v3_get_exception_address(struct nds32 *nds32,
231 uint32_t *address, uint32_t reason)
232 {
233 LOG_DEBUG("nds32_v3_get_exception_address");
234
235 struct aice_port_s *aice = target_to_aice(nds32->target);
236 struct target *target = nds32->target;
237 uint32_t edmsw;
238 uint32_t edm_cfg;
239 uint32_t match_bits;
240 uint32_t match_count;
241 int32_t i;
242 static int32_t number_of_hard_break;
243 uint32_t bp_control;
244
245 if (number_of_hard_break == 0) {
246 aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg);
247 number_of_hard_break = (edm_cfg & 0x7) + 1;
248 }
249
250 aice_read_debug_reg(aice, NDS_EDM_SR_EDMSW, &edmsw);
251 /* clear matching bits (write-one-clear) */
252 aice_write_debug_reg(aice, NDS_EDM_SR_EDMSW, edmsw);
253 match_bits = (edmsw >> 4) & 0xFF;
254 match_count = 0;
255 for (i = 0 ; i < number_of_hard_break ; i++) {
256 if (match_bits & (1 << i)) {
257 aice_read_debug_reg(aice, NDS_EDM_SR_BPA0 + i, address);
258 match_count++;
259
260 /* If target hits multiple read/access watchpoint,
261 * select the first one. */
262 aice_read_debug_reg(aice, NDS_EDM_SR_BPC0 + i, &bp_control);
263 if (0x3 == (bp_control & 0x3)) {
264 match_count = 1;
265 break;
266 }
267 }
268 }
269
270 if (match_count > 1) { /* multiple hits */
271 *address = 0;
272 return ERROR_OK;
273 } else if (match_count == 1) {
274 uint32_t val_pc;
275 uint32_t opcode;
276 struct nds32_instruction instruction;
277 struct watchpoint *wp;
278 bool hit;
279
280 nds32_get_mapped_reg(nds32, PC, &val_pc);
281
282 if ((NDS32_DEBUG_DATA_ADDR_WATCHPOINT_NEXT_PRECISE == reason) ||
283 (NDS32_DEBUG_DATA_VALUE_WATCHPOINT_NEXT_PRECISE == reason)) {
284 if (edmsw & 0x4) /* check EDMSW.IS_16BIT */
285 val_pc -= 2;
286 else
287 val_pc -= 4;
288 }
289
290 nds32_read_opcode(nds32, val_pc, &opcode);
291 nds32_evaluate_opcode(nds32, opcode, val_pc, &instruction);
292
293 LOG_DEBUG("PC: 0x%08x, access start: 0x%08x, end: 0x%08x", val_pc,
294 instruction.access_start, instruction.access_end);
295
296 /* check if multiple hits in the access range */
297 uint32_t in_range_watch_count = 0;
298 for (wp = target->watchpoints; wp; wp = wp->next) {
299 if ((instruction.access_start <= wp->address) &&
300 (wp->address < instruction.access_end))
301 in_range_watch_count++;
302 }
303 if (in_range_watch_count > 1) {
304 /* Hit LSMW instruction. */
305 *address = 0;
306 return ERROR_OK;
307 }
308
309 /* dispel false match */
310 hit = false;
311 for (wp = target->watchpoints; wp; wp = wp->next) {
312 if (((*address ^ wp->address) & (~wp->mask)) == 0) {
313 uint32_t watch_start;
314 uint32_t watch_end;
315
316 watch_start = wp->address;
317 watch_end = wp->address + wp->length;
318
319 if ((watch_end <= instruction.access_start) ||
320 (instruction.access_end <= watch_start))
321 continue;
322
323 hit = true;
324 break;
325 }
326 }
327
328 if (hit)
329 return ERROR_OK;
330 else
331 return ERROR_FAIL;
332 } else if (match_count == 0) {
333 /* global stop is precise exception */
334 if ((NDS32_DEBUG_LOAD_STORE_GLOBAL_STOP == reason) && nds32->global_stop) {
335 /* parse instruction to get correct access address */
336 uint32_t val_pc;
337 uint32_t opcode;
338 struct nds32_instruction instruction;
339
340 nds32_get_mapped_reg(nds32, PC, &val_pc);
341 nds32_read_opcode(nds32, val_pc, &opcode);
342 nds32_evaluate_opcode(nds32, opcode, val_pc, &instruction);
343
344 *address = instruction.access_start;
345
346 return ERROR_OK;
347 }
348 }
349
350 *address = 0xFFFFFFFF;
351 return ERROR_FAIL;
352 }
353
354 void nds32_v3_common_register_callback(struct nds32_v3_common_callback *callback)
355 {
356 v3_common_callback = callback;
357 }
358
359 /** target_type functions: */
360 /* target request support */
361 int nds32_v3_target_request_data(struct target *target,
362 uint32_t size, uint8_t *buffer)
363 {
364 /* AndesCore could use DTR register to communicate with OpenOCD
365 * to output messages
366 * Target data will be put in buffer
367 * The format of DTR is as follow
368 * DTR[31:16] => length, DTR[15:8] => size, DTR[7:0] => target_req_cmd
369 * target_req_cmd has three possible values:
370 * TARGET_REQ_TRACEMSG
371 * TARGET_REQ_DEBUGMSG
372 * TARGET_REQ_DEBUGCHAR
373 * if size == 0, target will call target_asciimsg(),
374 * else call target_hexmsg()
375 */
376 LOG_WARNING("Not implemented: %s", __func__);
377
378 return ERROR_OK;
379 }
380
381 int nds32_v3_soft_reset_halt(struct target *target)
382 {
383 struct aice_port_s *aice = target_to_aice(target);
384 return aice_assert_srst(aice, AICE_RESET_HOLD);
385 }
386
387 int nds32_v3_checksum_memory(struct target *target,
388 uint32_t address, uint32_t count, uint32_t *checksum)
389 {
390 LOG_WARNING("Not implemented: %s", __func__);
391
392 return ERROR_FAIL;
393 }
394
395 /**
396 * find out which watchpoint hits
397 * get exception address and compare the address to watchpoints
398 */
399 int nds32_v3_hit_watchpoint(struct target *target,
400 struct watchpoint **hit_watchpoint)
401 {
402 static struct watchpoint scan_all_watchpoint;
403
404 uint32_t exception_address;
405 struct watchpoint *wp;
406 struct nds32 *nds32 = target_to_nds32(target);
407
408 exception_address = nds32->watched_address;
409
410 if (exception_address == 0xFFFFFFFF)
411 return ERROR_FAIL;
412
413 if (exception_address == 0) {
414 scan_all_watchpoint.address = 0;
415 scan_all_watchpoint.rw = WPT_WRITE;
416 scan_all_watchpoint.next = 0;
417 scan_all_watchpoint.unique_id = 0x5CA8;
418
419 *hit_watchpoint = &scan_all_watchpoint;
420 return ERROR_OK;
421 }
422
423 for (wp = target->watchpoints; wp; wp = wp->next) {
424 if (((exception_address ^ wp->address) & (~wp->mask)) == 0) {
425 *hit_watchpoint = wp;
426
427 return ERROR_OK;
428 }
429 }
430
431 return ERROR_FAIL;
432 }
433
434 int nds32_v3_target_create_common(struct target *target, struct nds32 *nds32)
435 {
436 nds32->register_map = nds32_v3_register_mapping;
437 nds32->get_debug_reason = nds32_v3_get_debug_reason;
438 nds32->enter_debug_state = nds32_v3_debug_entry;
439 nds32->leave_debug_state = nds32_v3_leave_debug_state;
440 nds32->get_watched_address = nds32_v3_get_exception_address;
441
442 /* Init target->arch_info in nds32_init_arch_info().
443 * After this, user could use target_to_nds32() to get nds32 object */
444 nds32_init_arch_info(target, nds32);
445
446 return ERROR_OK;
447 }
448
449 int nds32_v3_run_algorithm(struct target *target,
450 int num_mem_params,
451 struct mem_param *mem_params,
452 int num_reg_params,
453 struct reg_param *reg_params,
454 uint32_t entry_point,
455 uint32_t exit_point,
456 int timeout_ms,
457 void *arch_info)
458 {
459 LOG_WARNING("Not implemented: %s", __func__);
460
461 return ERROR_FAIL;
462 }
463
464 int nds32_v3_read_buffer(struct target *target, uint32_t address,
465 uint32_t size, uint8_t *buffer)
466 {
467 struct nds32 *nds32 = target_to_nds32(target);
468 struct nds32_memory *memory = &(nds32->memory);
469
470 if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
471 (target->state != TARGET_HALTED)) {
472 LOG_WARNING("target was not halted");
473 return ERROR_TARGET_NOT_HALTED;
474 }
475
476 uint32_t physical_address;
477 /* BUG: If access range crosses multiple pages, the translation will not correct
478 * for second page or so. */
479
480 /* When DEX is set to one, hardware will enforce the following behavior without
481 * modifying the corresponding control bits in PSW.
482 *
483 * Disable all interrupts
484 * Become superuser mode
485 * Turn off IT/DT
486 * Use MMU_CFG.DE as the data access endian
487 * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted
488 * Disable audio special features
489 * Disable inline function call
490 *
491 * Because hardware will turn off IT/DT by default, it MUST translate virtual address
492 * to physical address.
493 */
494 if (ERROR_OK == target->type->virt2phys(target, address, &physical_address))
495 address = physical_address;
496 else
497 return ERROR_FAIL;
498
499 int result;
500 struct aice_port_s *aice = target_to_aice(target);
501 /* give arbitrary initial value to avoid warning messages */
502 enum nds_memory_access origin_access_channel = NDS_MEMORY_ACC_CPU;
503
504 if (nds32->hit_syscall) {
505 /* Use bus mode to access memory during virtual hosting */
506 origin_access_channel = memory->access_channel;
507 memory->access_channel = NDS_MEMORY_ACC_BUS;
508 aice_memory_access(aice, NDS_MEMORY_ACC_BUS);
509 }
510
511 result = nds32_read_buffer(target, address, size, buffer);
512
513 if (nds32->hit_syscall) {
514 /* Restore access_channel after virtual hosting */
515 memory->access_channel = origin_access_channel;
516 aice_memory_access(aice, origin_access_channel);
517 }
518
519 return result;
520 }
521
522 int nds32_v3_write_buffer(struct target *target, uint32_t address,
523 uint32_t size, const uint8_t *buffer)
524 {
525 struct nds32 *nds32 = target_to_nds32(target);
526 struct nds32_memory *memory = &(nds32->memory);
527
528 if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
529 (target->state != TARGET_HALTED)) {
530 LOG_WARNING("target was not halted");
531 return ERROR_TARGET_NOT_HALTED;
532 }
533
534 uint32_t physical_address;
535 /* BUG: If access range crosses multiple pages, the translation will not correct
536 * for second page or so. */
537
538 /* When DEX is set to one, hardware will enforce the following behavior without
539 * modifying the corresponding control bits in PSW.
540 *
541 * Disable all interrupts
542 * Become superuser mode
543 * Turn off IT/DT
544 * Use MMU_CFG.DE as the data access endian
545 * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted
546 * Disable audio special features
547 * Disable inline function call
548 *
549 * Because hardware will turn off IT/DT by default, it MUST translate virtual address
550 * to physical address.
551 */
552 if (ERROR_OK == target->type->virt2phys(target, address, &physical_address))
553 address = physical_address;
554 else
555 return ERROR_FAIL;
556
557 if (nds32->hit_syscall) {
558 struct aice_port_s *aice = target_to_aice(target);
559 enum nds_memory_access origin_access_channel;
560 origin_access_channel = memory->access_channel;
561
562 /* If target has no cache, use BUS mode to access memory. */
563 if ((memory->dcache.line_size == 0)
564 || (memory->dcache.enable == false)) {
565 /* There is no Dcache or Dcache is disabled. */
566 memory->access_channel = NDS_MEMORY_ACC_BUS;
567 aice_memory_access(aice, NDS_MEMORY_ACC_BUS);
568 }
569
570 int result;
571 result = nds32_gdb_fileio_write_memory(nds32, address, size, buffer);
572
573 if (NDS_MEMORY_ACC_CPU == origin_access_channel) {
574 memory->access_channel = NDS_MEMORY_ACC_CPU;
575 aice_memory_access(aice, NDS_MEMORY_ACC_CPU);
576 }
577
578 return result;
579 }
580
581 return nds32_write_buffer(target, address, size, buffer);
582 }
583
584 int nds32_v3_read_memory(struct target *target, uint32_t address,
585 uint32_t size, uint32_t count, uint8_t *buffer)
586 {
587 struct nds32 *nds32 = target_to_nds32(target);
588 struct nds32_memory *memory = &(nds32->memory);
589
590 if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
591 (target->state != TARGET_HALTED)) {
592 LOG_WARNING("target was not halted");
593 return ERROR_TARGET_NOT_HALTED;
594 }
595
596 uint32_t physical_address;
597 /* BUG: If access range crosses multiple pages, the translation will not correct
598 * for second page or so. */
599
600 /* When DEX is set to one, hardware will enforce the following behavior without
601 * modifying the corresponding control bits in PSW.
602 *
603 * Disable all interrupts
604 * Become superuser mode
605 * Turn off IT/DT
606 * Use MMU_CFG.DE as the data access endian
607 * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted
608 * Disable audio special features
609 * Disable inline function call
610 *
611 * Because hardware will turn off IT/DT by default, it MUST translate virtual address
612 * to physical address.
613 */
614 if (ERROR_OK == target->type->virt2phys(target, address, &physical_address))
615 address = physical_address;
616 else
617 return ERROR_FAIL;
618
619 struct aice_port_s *aice = target_to_aice(target);
620 /* give arbitrary initial value to avoid warning messages */
621 enum nds_memory_access origin_access_channel = NDS_MEMORY_ACC_CPU;
622 int result;
623
624 if (nds32->hit_syscall) {
625 /* Use bus mode to access memory during virtual hosting */
626 origin_access_channel = memory->access_channel;
627 memory->access_channel = NDS_MEMORY_ACC_BUS;
628 aice_memory_access(aice, NDS_MEMORY_ACC_BUS);
629 }
630
631 result = nds32_read_memory(target, address, size, count, buffer);
632
633 if (nds32->hit_syscall) {
634 /* Restore access_channel after virtual hosting */
635 memory->access_channel = origin_access_channel;
636 aice_memory_access(aice, origin_access_channel);
637 }
638
639 return result;
640 }
641
642 int nds32_v3_write_memory(struct target *target, uint32_t address,
643 uint32_t size, uint32_t count, const uint8_t *buffer)
644 {
645 struct nds32 *nds32 = target_to_nds32(target);
646 struct nds32_memory *memory = &(nds32->memory);
647
648 if ((NDS_MEMORY_ACC_CPU == memory->access_channel) &&
649 (target->state != TARGET_HALTED)) {
650 LOG_WARNING("target was not halted");
651 return ERROR_TARGET_NOT_HALTED;
652 }
653
654 uint32_t physical_address;
655 /* BUG: If access range crosses multiple pages, the translation will not correct
656 * for second page or so. */
657
658 /* When DEX is set to one, hardware will enforce the following behavior without
659 * modifying the corresponding control bits in PSW.
660 *
661 * Disable all interrupts
662 * Become superuser mode
663 * Turn off IT/DT
664 * Use MMU_CFG.DE as the data access endian
665 * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted
666 * Disable audio special features
667 * Disable inline function call
668 *
669 * Because hardware will turn off IT/DT by default, it MUST translate virtual address
670 * to physical address.
671 */
672 if (ERROR_OK == target->type->virt2phys(target, address, &physical_address))
673 address = physical_address;
674 else
675 return ERROR_FAIL;
676
677 return nds32_write_memory(target, address, size, count, buffer);
678 }
679
680 int nds32_v3_init_target(struct command_context *cmd_ctx,
681 struct target *target)
682 {
683 /* Initialize anything we can set up without talking to the target */
684 struct nds32 *nds32 = target_to_nds32(target);
685
686 nds32_init(nds32);
687
688 target->fileio_info = malloc(sizeof(struct gdb_fileio_info));
689 target->fileio_info->identifier = NULL;
690
691 return ERROR_OK;
692 }

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)