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

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)