]> git.sur5r.net Git - openocd/blob - src/target/nds32_cmd.c
ffd606129e94f196f7f4c06b65648fe6953baec5
[openocd] / src / target / nds32_cmd.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/command.h>
26 #include "nds32.h"
27 #include "nds32_aice.h"
28 #include "nds32_disassembler.h"
29
30 extern struct nds32_edm_operation nds32_edm_ops[NDS32_EDM_OPERATION_MAX_NUM];
31 extern uint32_t nds32_edm_ops_num;
32
33 static const char *const NDS_MEMORY_ACCESS_NAME[] = {
34         "BUS",
35         "CPU",
36 };
37
38 static const char *const NDS_MEMORY_SELECT_NAME[] = {
39         "AUTO",
40         "MEM",
41         "ILM",
42         "DLM",
43 };
44
45 COMMAND_HANDLER(handle_nds32_dssim_command)
46 {
47         struct target *target = get_current_target(CMD_CTX);
48         struct nds32 *nds32 = target_to_nds32(target);
49
50         if (!is_nds32(nds32)) {
51                 command_print(CMD_CTX, "current target isn't an Andes core");
52                 return ERROR_FAIL;
53         }
54
55         if (CMD_ARGC > 0) {
56                 if (strcmp(CMD_ARGV[0], "on") == 0)
57                         nds32->step_isr_enable = true;
58                 if (strcmp(CMD_ARGV[0], "off") == 0)
59                         nds32->step_isr_enable = false;
60         }
61
62         command_print(CMD_CTX, "%s: $INT_MASK.DSSIM: %d", target_name(target),
63                         nds32->step_isr_enable);
64
65         return ERROR_OK;
66 }
67
68 COMMAND_HANDLER(handle_nds32_memory_access_command)
69 {
70         struct target *target = get_current_target(CMD_CTX);
71         struct nds32 *nds32 = target_to_nds32(target);
72         struct aice_port_s *aice = target_to_aice(target);
73         struct nds32_memory *memory = &(nds32->memory);
74
75         if (!is_nds32(nds32)) {
76                 command_print(CMD_CTX, "current target isn't an Andes core");
77                 return ERROR_FAIL;
78         }
79
80         if (CMD_ARGC > 0) {
81                 if (strcmp(CMD_ARGV[0], "bus") == 0)
82                         memory->access_channel = NDS_MEMORY_ACC_BUS;
83                 else if (strcmp(CMD_ARGV[0], "cpu") == 0)
84                         memory->access_channel = NDS_MEMORY_ACC_CPU;
85                 else /* default access channel is NDS_MEMORY_ACC_CPU */
86                         memory->access_channel = NDS_MEMORY_ACC_CPU;
87
88                 LOG_DEBUG("memory access channel is changed to %s",
89                                 NDS_MEMORY_ACCESS_NAME[memory->access_channel]);
90
91                 aice_memory_access(aice, memory->access_channel);
92         } else {
93                 command_print(CMD_CTX, "%s: memory access channel: %s",
94                                 target_name(target),
95                                 NDS_MEMORY_ACCESS_NAME[memory->access_channel]);
96         }
97
98         return ERROR_OK;
99 }
100
101 COMMAND_HANDLER(handle_nds32_memory_mode_command)
102 {
103         struct target *target = get_current_target(CMD_CTX);
104         struct nds32 *nds32 = target_to_nds32(target);
105         struct aice_port_s *aice = target_to_aice(target);
106
107         if (!is_nds32(nds32)) {
108                 command_print(CMD_CTX, "current target isn't an Andes core");
109                 return ERROR_FAIL;
110         }
111
112         if (CMD_ARGC > 0) {
113
114                 if (nds32->edm.access_control == false) {
115                         command_print(CMD_CTX, "%s does not support ACC_CTL. "
116                                         "Set memory mode to MEMORY", target_name(target));
117                         nds32->memory.mode = NDS_MEMORY_SELECT_MEM;
118                 } else if (nds32->edm.direct_access_local_memory == false) {
119                         command_print(CMD_CTX, "%s does not support direct access "
120                                         "local memory. Set memory mode to MEMORY",
121                                         target_name(target));
122                         nds32->memory.mode = NDS_MEMORY_SELECT_MEM;
123
124                         /* set to ACC_CTL */
125                         aice_memory_mode(aice, nds32->memory.mode);
126                 } else {
127                         if (strcmp(CMD_ARGV[0], "auto") == 0) {
128                                 nds32->memory.mode = NDS_MEMORY_SELECT_AUTO;
129                         } else if (strcmp(CMD_ARGV[0], "mem") == 0) {
130                                 nds32->memory.mode = NDS_MEMORY_SELECT_MEM;
131                         } else if (strcmp(CMD_ARGV[0], "ilm") == 0) {
132                                 if (nds32->memory.ilm_base == 0)
133                                         command_print(CMD_CTX, "%s does not support ILM",
134                                                         target_name(target));
135                                 else
136                                         nds32->memory.mode = NDS_MEMORY_SELECT_ILM;
137                         } else if (strcmp(CMD_ARGV[0], "dlm") == 0) {
138                                 if (nds32->memory.dlm_base == 0)
139                                         command_print(CMD_CTX, "%s does not support DLM",
140                                                         target_name(target));
141                                 else
142                                         nds32->memory.mode = NDS_MEMORY_SELECT_DLM;
143                         }
144
145                         /* set to ACC_CTL */
146                         aice_memory_mode(aice, nds32->memory.mode);
147                 }
148         }
149
150         command_print(CMD_CTX, "%s: memory mode: %s",
151                         target_name(target),
152                         NDS_MEMORY_SELECT_NAME[nds32->memory.mode]);
153
154         return ERROR_OK;
155 }
156
157 COMMAND_HANDLER(handle_nds32_cache_command)
158 {
159         struct target *target = get_current_target(CMD_CTX);
160         struct nds32 *nds32 = target_to_nds32(target);
161         struct aice_port_s *aice = target_to_aice(target);
162         struct nds32_cache *icache = &(nds32->memory.icache);
163         struct nds32_cache *dcache = &(nds32->memory.dcache);
164         int result;
165
166         if (!is_nds32(nds32)) {
167                 command_print(CMD_CTX, "current target isn't an Andes core");
168                 return ERROR_FAIL;
169         }
170
171         if (CMD_ARGC > 0) {
172
173                 if (strcmp(CMD_ARGV[0], "invalidate") == 0) {
174                         if ((dcache->line_size != 0) && (dcache->enable == true)) {
175                                 /* D$ write back */
176                                 result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_WBALL, 0);
177                                 if (result != ERROR_OK) {
178                                         command_print(CMD_CTX, "%s: Write back data cache...failed",
179                                                         target_name(target));
180                                         return result;
181                                 }
182
183                                 command_print(CMD_CTX, "%s: Write back data cache...done",
184                                                 target_name(target));
185
186                                 /* D$ invalidate */
187                                 result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_INVALALL, 0);
188                                 if (result != ERROR_OK) {
189                                         command_print(CMD_CTX, "%s: Invalidate data cache...failed",
190                                                         target_name(target));
191                                         return result;
192                                 }
193
194                                 command_print(CMD_CTX, "%s: Invalidate data cache...done",
195                                                 target_name(target));
196                         } else {
197                                 if (dcache->line_size == 0)
198                                         command_print(CMD_CTX, "%s: No data cache",
199                                                         target_name(target));
200                                 else
201                                         command_print(CMD_CTX, "%s: Data cache disabled",
202                                                         target_name(target));
203                         }
204
205                         if ((icache->line_size != 0) && (icache->enable == true)) {
206                                 /* I$ invalidate */
207                                 result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1I_INVALALL, 0);
208                                 if (result != ERROR_OK) {
209                                         command_print(CMD_CTX, "%s: Invalidate instruction cache...failed",
210                                                         target_name(target));
211                                         return result;
212                                 }
213
214                                 command_print(CMD_CTX, "%s: Invalidate instruction cache...done",
215                                                 target_name(target));
216                         } else {
217                                 if (icache->line_size == 0)
218                                         command_print(CMD_CTX, "%s: No instruction cache",
219                                                         target_name(target));
220                                 else
221                                         command_print(CMD_CTX, "%s: Instruction cache disabled",
222                                                         target_name(target));
223                         }
224                 } else
225                         command_print(CMD_CTX, "No valid parameter");
226         }
227
228         return ERROR_OK;
229 }
230
231 COMMAND_HANDLER(handle_nds32_icache_command)
232 {
233         struct target *target = get_current_target(CMD_CTX);
234         struct nds32 *nds32 = target_to_nds32(target);
235         struct aice_port_s *aice = target_to_aice(target);
236         struct nds32_cache *icache = &(nds32->memory.icache);
237         int result;
238
239         if (!is_nds32(nds32)) {
240                 command_print(CMD_CTX, "current target isn't an Andes core");
241                 return ERROR_FAIL;
242         }
243
244         if (CMD_ARGC > 0) {
245
246                 if (icache->line_size == 0) {
247                         command_print(CMD_CTX, "%s: No instruction cache",
248                                         target_name(target));
249                         return ERROR_OK;
250                 }
251
252                 if (strcmp(CMD_ARGV[0], "invalidate") == 0) {
253                         if (icache->enable == true) {
254                                 /* I$ invalidate */
255                                 result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1I_INVALALL, 0);
256                                 if (result != ERROR_OK) {
257                                         command_print(CMD_CTX, "%s: Invalidate instruction cache...failed",
258                                                         target_name(target));
259                                         return result;
260                                 }
261
262                                 command_print(CMD_CTX, "%s: Invalidate instruction cache...done",
263                                                 target_name(target));
264                         } else {
265                                 command_print(CMD_CTX, "%s: Instruction cache disabled",
266                                                 target_name(target));
267                         }
268                 } else if (strcmp(CMD_ARGV[0], "enable") == 0) {
269                         uint32_t value;
270                         nds32_get_mapped_reg(nds32, IR8, &value);
271                         nds32_set_mapped_reg(nds32, IR8, value | 0x1);
272                 } else if (strcmp(CMD_ARGV[0], "disable") == 0) {
273                         uint32_t value;
274                         nds32_get_mapped_reg(nds32, IR8, &value);
275                         nds32_set_mapped_reg(nds32, IR8, value & ~0x1);
276                 } else if (strcmp(CMD_ARGV[0], "dump") == 0) {
277                         /* TODO: dump cache content */
278                 } else {
279                         command_print(CMD_CTX, "%s: No valid parameter", target_name(target));
280                 }
281         }
282
283         return ERROR_OK;
284 }
285
286 COMMAND_HANDLER(handle_nds32_dcache_command)
287 {
288         struct target *target = get_current_target(CMD_CTX);
289         struct nds32 *nds32 = target_to_nds32(target);
290         struct aice_port_s *aice = target_to_aice(target);
291         struct nds32_cache *dcache = &(nds32->memory.dcache);
292         int result;
293
294         if (!is_nds32(nds32)) {
295                 command_print(CMD_CTX, "current target isn't an Andes core");
296                 return ERROR_FAIL;
297         }
298
299         if (CMD_ARGC > 0) {
300
301                 if (dcache->line_size == 0) {
302                         command_print(CMD_CTX, "%s: No data cache", target_name(target));
303                         return ERROR_OK;
304                 }
305
306                 if (strcmp(CMD_ARGV[0], "invalidate") == 0) {
307                         if (dcache->enable == true) {
308                                 /* D$ write back */
309                                 result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_WBALL, 0);
310                                 if (result != ERROR_OK) {
311                                         command_print(CMD_CTX, "%s: Write back data cache...failed",
312                                                         target_name(target));
313                                         return result;
314                                 }
315
316                                 command_print(CMD_CTX, "%s: Write back data cache...done",
317                                                 target_name(target));
318
319                                 /* D$ invalidate */
320                                 result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_INVALALL, 0);
321                                 if (result != ERROR_OK) {
322                                         command_print(CMD_CTX, "%s: Invalidate data cache...failed",
323                                                         target_name(target));
324                                         return result;
325                                 }
326
327                                 command_print(CMD_CTX, "%s: Invalidate data cache...done",
328                                                 target_name(target));
329                         } else {
330                                 command_print(CMD_CTX, "%s: Data cache disabled",
331                                                 target_name(target));
332                         }
333                 } else if (strcmp(CMD_ARGV[0], "enable") == 0) {
334                         uint32_t value;
335                         nds32_get_mapped_reg(nds32, IR8, &value);
336                         nds32_set_mapped_reg(nds32, IR8, value | 0x2);
337                 } else if (strcmp(CMD_ARGV[0], "disable") == 0) {
338                         uint32_t value;
339                         nds32_get_mapped_reg(nds32, IR8, &value);
340                         nds32_set_mapped_reg(nds32, IR8, value & ~0x2);
341                 } else if (strcmp(CMD_ARGV[0], "dump") == 0) {
342                         /* TODO: dump cache content */
343                 } else {
344                         command_print(CMD_CTX, "%s: No valid parameter", target_name(target));
345                 }
346         }
347
348         return ERROR_OK;
349 }
350
351 COMMAND_HANDLER(handle_nds32_auto_break_command)
352 {
353         struct target *target = get_current_target(CMD_CTX);
354         struct nds32 *nds32 = target_to_nds32(target);
355
356         if (!is_nds32(nds32)) {
357                 command_print(CMD_CTX, "current target isn't an Andes core");
358                 return ERROR_FAIL;
359         }
360
361         if (CMD_ARGC > 0) {
362                 if (strcmp(CMD_ARGV[0], "on") == 0)
363                         nds32->auto_convert_hw_bp = true;
364                 if (strcmp(CMD_ARGV[0], "off") == 0)
365                         nds32->auto_convert_hw_bp = false;
366         }
367
368         if (nds32->auto_convert_hw_bp)
369                 command_print(CMD_CTX, "%s: convert sw break to hw break on ROM: on",
370                                 target_name(target));
371         else
372                 command_print(CMD_CTX, "%s: convert sw break to hw break on ROM: off",
373                                 target_name(target));
374
375         return ERROR_OK;
376 }
377
378 COMMAND_HANDLER(handle_nds32_virtual_hosting_command)
379 {
380         struct target *target = get_current_target(CMD_CTX);
381         struct nds32 *nds32 = target_to_nds32(target);
382
383         if (!is_nds32(nds32)) {
384                 command_print(CMD_CTX, "current target isn't an Andes core");
385                 return ERROR_FAIL;
386         }
387
388         if (CMD_ARGC > 0) {
389                 if (strcmp(CMD_ARGV[0], "on") == 0)
390                         nds32->virtual_hosting = true;
391                 if (strcmp(CMD_ARGV[0], "off") == 0)
392                         nds32->virtual_hosting = false;
393         }
394
395         if (nds32->virtual_hosting)
396                 command_print(CMD_CTX, "%s: virtual hosting: on", target_name(target));
397         else
398                 command_print(CMD_CTX, "%s: virtual hosting: off", target_name(target));
399
400         return ERROR_OK;
401 }
402
403 COMMAND_HANDLER(handle_nds32_global_stop_command)
404 {
405         struct target *target = get_current_target(CMD_CTX);
406         struct nds32 *nds32 = target_to_nds32(target);
407
408         if (!is_nds32(nds32)) {
409                 command_print(CMD_CTX, "current target isn't an Andes core");
410                 return ERROR_FAIL;
411         }
412
413         if (CMD_ARGC > 0) {
414                 if (strcmp(CMD_ARGV[0], "on") == 0)
415                         nds32->global_stop = true;
416                 if (strcmp(CMD_ARGV[0], "off") == 0)
417                         nds32->global_stop = false;
418         }
419
420         if (nds32->global_stop)
421                 LOG_INFO("%s: global stop: on", target_name(target));
422         else
423                 LOG_INFO("%s: global stop: off", target_name(target));
424
425         return ERROR_OK;
426 }
427
428 COMMAND_HANDLER(handle_nds32_soft_reset_halt_command)
429 {
430         struct target *target = get_current_target(CMD_CTX);
431         struct nds32 *nds32 = target_to_nds32(target);
432
433         if (!is_nds32(nds32)) {
434                 command_print(CMD_CTX, "current target isn't an Andes core");
435                 return ERROR_FAIL;
436         }
437
438         if (CMD_ARGC > 0) {
439                 if (strcmp(CMD_ARGV[0], "on") == 0)
440                         nds32->soft_reset_halt = true;
441                 if (strcmp(CMD_ARGV[0], "off") == 0)
442                         nds32->soft_reset_halt = false;
443         }
444
445         if (nds32->soft_reset_halt)
446                 LOG_INFO("%s: soft-reset-halt: on", target_name(target));
447         else
448                 LOG_INFO("%s: soft-reset-halt: off", target_name(target));
449
450         return ERROR_OK;
451 }
452
453 COMMAND_HANDLER(handle_nds32_boot_time_command)
454 {
455         struct target *target = get_current_target(CMD_CTX);
456         struct nds32 *nds32 = target_to_nds32(target);
457
458         if (!is_nds32(nds32)) {
459                 command_print(CMD_CTX, "current target isn't an Andes core");
460                 return ERROR_FAIL;
461         }
462
463         if (CMD_ARGC > 0)
464                 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], nds32->boot_time);
465
466         return ERROR_OK;
467 }
468
469 COMMAND_HANDLER(handle_nds32_login_edm_passcode_command)
470 {
471         struct target *target = get_current_target(CMD_CTX);
472         struct nds32 *nds32 = target_to_nds32(target);
473
474         if (!is_nds32(nds32)) {
475                 command_print(CMD_CTX, "current target isn't an Andes core");
476                 return ERROR_FAIL;
477         }
478
479         nds32->edm_passcode = strdup(CMD_ARGV[0]);
480
481         return ERROR_OK;
482 }
483
484 COMMAND_HANDLER(handle_nds32_login_edm_operation_command)
485 {
486         struct target *target = get_current_target(CMD_CTX);
487         struct nds32 *nds32 = target_to_nds32(target);
488
489         if (!is_nds32(nds32)) {
490                 command_print(CMD_CTX, "current target isn't an Andes core");
491                 return ERROR_FAIL;
492         }
493
494         if (CMD_ARGC > 1) {
495
496                 uint32_t misc_reg_no;
497                 uint32_t data;
498
499                 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], misc_reg_no);
500                 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], data);
501
502                 if (nds32_edm_ops_num >= NDS32_EDM_OPERATION_MAX_NUM)
503                         return ERROR_FAIL;
504
505                 /* Just save the operation. Execute it in nds32_login() */
506                 nds32_edm_ops[nds32_edm_ops_num].reg_no = misc_reg_no;
507                 nds32_edm_ops[nds32_edm_ops_num].value = data;
508                 nds32_edm_ops_num++;
509         } else
510                 return ERROR_FAIL;
511
512         return ERROR_OK;
513 }
514
515 COMMAND_HANDLER(handle_nds32_reset_halt_as_init_command)
516 {
517         struct target *target = get_current_target(CMD_CTX);
518         struct nds32 *nds32 = target_to_nds32(target);
519
520         if (!is_nds32(nds32)) {
521                 command_print(CMD_CTX, "current target isn't an Andes core");
522                 return ERROR_FAIL;
523         }
524
525         if (CMD_ARGC > 0) {
526                 if (strcmp(CMD_ARGV[0], "on") == 0)
527                         nds32->reset_halt_as_examine = true;
528                 if (strcmp(CMD_ARGV[0], "off") == 0)
529                         nds32->reset_halt_as_examine = false;
530         }
531
532         return ERROR_OK;
533 }
534
535 COMMAND_HANDLER(handle_nds32_keep_target_edm_ctl_command)
536 {
537         struct target *target = get_current_target(CMD_CTX);
538         struct nds32 *nds32 = target_to_nds32(target);
539
540         if (!is_nds32(nds32)) {
541                 command_print(CMD_CTX, "current target isn't an Andes core");
542                 return ERROR_FAIL;
543         }
544
545         if (CMD_ARGC > 0) {
546                 if (strcmp(CMD_ARGV[0], "on") == 0)
547                         nds32->keep_target_edm_ctl = true;
548                 if (strcmp(CMD_ARGV[0], "off") == 0)
549                         nds32->keep_target_edm_ctl = false;
550         }
551
552         return ERROR_OK;
553 }
554
555 COMMAND_HANDLER(handle_nds32_decode_command)
556 {
557         struct target *target = get_current_target(CMD_CTX);
558         struct nds32 *nds32 = target_to_nds32(target);
559
560         if (!is_nds32(nds32)) {
561                 command_print(CMD_CTX, "current target isn't an Andes core");
562                 return ERROR_FAIL;
563         }
564
565         if (CMD_ARGC > 1) {
566
567                 uint32_t addr;
568                 uint32_t insn_count;
569                 uint32_t opcode;
570                 uint32_t read_addr;
571                 uint32_t i;
572                 struct nds32_instruction instruction;
573
574                 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
575                 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], insn_count);
576
577                 read_addr = addr;
578                 i = 0;
579                 while (i < insn_count) {
580                         if (ERROR_OK != nds32_read_opcode(nds32, read_addr, &opcode))
581                                 return ERROR_FAIL;
582                         if (ERROR_OK != nds32_evaluate_opcode(nds32, opcode,
583                                                 read_addr, &instruction))
584                                 return ERROR_FAIL;
585
586                         command_print(CMD_CTX, "%s", instruction.text);
587
588                         read_addr += instruction.instruction_size;
589                         i++;
590                 }
591         } else if (CMD_ARGC == 1) {
592
593                 uint32_t addr;
594                 uint32_t opcode;
595                 struct nds32_instruction instruction;
596
597                 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
598
599                 if (ERROR_OK != nds32_read_opcode(nds32, addr, &opcode))
600                         return ERROR_FAIL;
601                 if (ERROR_OK != nds32_evaluate_opcode(nds32, opcode, addr, &instruction))
602                         return ERROR_FAIL;
603
604                 command_print(CMD_CTX, "%s", instruction.text);
605         } else
606                 return ERROR_FAIL;
607
608         return ERROR_OK;
609 }
610
611 COMMAND_HANDLER(handle_nds32_word_access_mem_command)
612 {
613         struct target *target = get_current_target(CMD_CTX);
614         struct nds32 *nds32 = target_to_nds32(target);
615
616         if (!is_nds32(nds32)) {
617                 command_print(CMD_CTX, "current target isn't an Andes core");
618                 return ERROR_FAIL;
619         }
620
621         if (CMD_ARGC > 0) {
622                 if (strcmp(CMD_ARGV[0], "on") == 0)
623                         nds32->word_access_mem = true;
624                 if (strcmp(CMD_ARGV[0], "off") == 0)
625                         nds32->word_access_mem = false;
626         }
627
628         return ERROR_OK;
629 }
630
631 COMMAND_HANDLER(handle_nds32_query_target_command)
632 {
633         struct target *target = get_current_target(CMD_CTX);
634         struct nds32 *nds32 = target_to_nds32(target);
635
636         if (!is_nds32(nds32)) {
637                 command_print(CMD_CTX, "current target isn't an Andes core");
638                 return ERROR_FAIL;
639         }
640
641         command_print(CMD_CTX, "OCD");
642
643         return ERROR_OK;
644 }
645
646 COMMAND_HANDLER(handle_nds32_query_endian_command)
647 {
648         struct target *target = get_current_target(CMD_CTX);
649         struct nds32 *nds32 = target_to_nds32(target);
650
651         if (!is_nds32(nds32)) {
652                 command_print(CMD_CTX, "current target isn't an Andes core");
653                 return ERROR_FAIL;
654         }
655
656         uint32_t value_psw;
657         nds32_get_mapped_reg(nds32, IR0, &value_psw);
658
659         if (value_psw & 0x20)
660                 command_print(CMD_CTX, "%s: BE", target_name(target));
661         else
662                 command_print(CMD_CTX, "%s: LE", target_name(target));
663
664         return ERROR_OK;
665 }
666
667 COMMAND_HANDLER(handle_nds32_query_cpuid_command)
668 {
669         struct target *target = get_current_target(CMD_CTX);
670         struct nds32 *nds32 = target_to_nds32(target);
671
672         if (!is_nds32(nds32)) {
673                 command_print(CMD_CTX, "current target isn't an Andes core");
674                 return ERROR_FAIL;
675         }
676
677         command_print(CMD_CTX, "CPUID: %s", target_name(target));
678
679         return ERROR_OK;
680 }
681
682 static int jim_nds32_bulk_write(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
683 {
684         const char *cmd_name = Jim_GetString(argv[0], NULL);
685
686         Jim_GetOptInfo goi;
687         Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
688
689         if (goi.argc < 3) {
690                 Jim_SetResultFormatted(goi.interp,
691                                 "usage: %s <address> <count> <data>", cmd_name);
692                 return JIM_ERR;
693         }
694
695         int e;
696         jim_wide address;
697         e = Jim_GetOpt_Wide(&goi, &address);
698         if (e != JIM_OK)
699                 return e;
700
701         jim_wide count;
702         e = Jim_GetOpt_Wide(&goi, &count);
703         if (e != JIM_OK)
704                 return e;
705
706         uint32_t *data = malloc(count * sizeof(uint32_t));
707         if (data == NULL)
708                 return JIM_ERR;
709
710         jim_wide i;
711         for (i = 0; i < count; i++) {
712                 jim_wide tmp;
713                 e = Jim_GetOpt_Wide(&goi, &tmp);
714                 if (e != JIM_OK) {
715                         free(data);
716                         return e;
717                 }
718                 data[i] = (uint32_t)tmp;
719         }
720
721         /* all args must be consumed */
722         if (goi.argc != 0) {
723                 free(data);
724                 return JIM_ERR;
725         }
726
727         struct target *target = Jim_CmdPrivData(goi.interp);
728         int result;
729
730         result = target_write_buffer(target, address, count * 4, (const uint8_t *)data);
731
732         free(data);
733
734         return result;
735 }
736
737 static int jim_nds32_multi_write(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
738 {
739         const char *cmd_name = Jim_GetString(argv[0], NULL);
740
741         Jim_GetOptInfo goi;
742         Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
743
744         if (goi.argc < 3) {
745                 Jim_SetResultFormatted(goi.interp,
746                                 "usage: %s # of pairs [<address> <data>]+", cmd_name);
747                 return JIM_ERR;
748         }
749
750         int e;
751         jim_wide num_of_pairs;
752         e = Jim_GetOpt_Wide(&goi, &num_of_pairs);
753         if (e != JIM_OK)
754                 return e;
755
756         struct target *target = Jim_CmdPrivData(goi.interp);
757         struct aice_port_s *aice = target_to_aice(target);
758         int result;
759         uint32_t address;
760         uint32_t data;
761         jim_wide i;
762
763         aice_set_command_mode(aice, AICE_COMMAND_MODE_PACK);
764         for (i = 0; i < num_of_pairs; i++) {
765                 jim_wide tmp;
766                 e = Jim_GetOpt_Wide(&goi, &tmp);
767                 if (e != JIM_OK)
768                         break;
769                 address = (uint32_t)tmp;
770
771                 e = Jim_GetOpt_Wide(&goi, &tmp);
772                 if (e != JIM_OK)
773                         break;
774                 data = (uint32_t)tmp;
775
776                 result = target_write_buffer(target, address, 4, (const uint8_t *)&data);
777                 if (result != ERROR_OK)
778                         break;
779         }
780         aice_set_command_mode(aice, AICE_COMMAND_MODE_NORMAL);
781
782         /* all args must be consumed */
783         if (goi.argc != 0)
784                 return JIM_ERR;
785
786         return ERROR_OK;
787 }
788
789 static int jim_nds32_bulk_read(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
790 {
791         const char *cmd_name = Jim_GetString(argv[0], NULL);
792
793         Jim_GetOptInfo goi;
794         Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
795
796         if (goi.argc < 2) {
797                 Jim_SetResultFormatted(goi.interp,
798                                 "usage: %s <address> <count>", cmd_name);
799                 return JIM_ERR;
800         }
801
802         int e;
803         jim_wide address;
804         e = Jim_GetOpt_Wide(&goi, &address);
805         if (e != JIM_OK)
806                 return e;
807
808         jim_wide count;
809         e = Jim_GetOpt_Wide(&goi, &count);
810         if (e != JIM_OK)
811                 return e;
812
813         /* all args must be consumed */
814         if (goi.argc != 0)
815                 return JIM_ERR;
816
817         struct target *target = Jim_CmdPrivData(goi.interp);
818         uint32_t *data = malloc(count * sizeof(uint32_t));
819         int result;
820         result = target_read_buffer(target, address, count * 4, (uint8_t *)data);
821         char data_str[11];
822
823         jim_wide i;
824         Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
825         for (i = 0; i < count; i++) {
826                 sprintf(data_str, "0x%08" PRIx32 " ", data[i]);
827                 Jim_AppendStrings(interp, Jim_GetResult(interp), data_str, NULL);
828         }
829
830         free(data);
831
832         return result;
833 }
834
835 static int jim_nds32_read_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
836 {
837         const char *cmd_name = Jim_GetString(argv[0], NULL);
838
839         Jim_GetOptInfo goi;
840         Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
841
842         if (goi.argc < 1) {
843                 Jim_SetResultFormatted(goi.interp,
844                                 "usage: %s <edm_sr_name>", cmd_name);
845                 return JIM_ERR;
846         }
847
848         int e;
849         const char *edm_sr_name;
850         int edm_sr_name_len;
851         e = Jim_GetOpt_String(&goi, &edm_sr_name, &edm_sr_name_len);
852         if (e != JIM_OK)
853                 return e;
854
855         /* all args must be consumed */
856         if (goi.argc != 0)
857                 return JIM_ERR;
858
859         uint32_t edm_sr_number;
860         uint32_t edm_sr_value;
861         if (strncmp(edm_sr_name, "edm_dtr", edm_sr_name_len) == 0)
862                 edm_sr_number = NDS_EDM_SR_EDM_DTR;
863         else if (strncmp(edm_sr_name, "edmsw", edm_sr_name_len) == 0)
864                 edm_sr_number = NDS_EDM_SR_EDMSW;
865         else
866                 return ERROR_FAIL;
867
868         struct target *target = Jim_CmdPrivData(goi.interp);
869         struct aice_port_s *aice = target_to_aice(target);
870         char data_str[11];
871
872         aice_read_debug_reg(aice, edm_sr_number, &edm_sr_value);
873
874         sprintf(data_str, "0x%08" PRIx32, edm_sr_value);
875         Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
876         Jim_AppendStrings(interp, Jim_GetResult(interp), data_str, NULL);
877
878         return ERROR_OK;
879 }
880
881 static int jim_nds32_write_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
882 {
883         const char *cmd_name = Jim_GetString(argv[0], NULL);
884
885         Jim_GetOptInfo goi;
886         Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
887
888         if (goi.argc < 2) {
889                 Jim_SetResultFormatted(goi.interp,
890                                 "usage: %s <edm_sr_name> <value>", cmd_name);
891                 return JIM_ERR;
892         }
893
894         int e;
895         const char *edm_sr_name;
896         int edm_sr_name_len;
897         e = Jim_GetOpt_String(&goi, &edm_sr_name, &edm_sr_name_len);
898         if (e != JIM_OK)
899                 return e;
900
901         jim_wide value;
902         e = Jim_GetOpt_Wide(&goi, &value);
903         if (e != JIM_OK)
904                 return e;
905
906         /* all args must be consumed */
907         if (goi.argc != 0)
908                 return JIM_ERR;
909
910         uint32_t edm_sr_number;
911         if (strncmp(edm_sr_name, "edm_dtr", edm_sr_name_len) == 0)
912                 edm_sr_number = NDS_EDM_SR_EDM_DTR;
913         else
914                 return ERROR_FAIL;
915
916         struct target *target = Jim_CmdPrivData(goi.interp);
917         struct aice_port_s *aice = target_to_aice(target);
918
919         aice_write_debug_reg(aice, edm_sr_number, value);
920
921         return ERROR_OK;
922 }
923
924 static const struct command_registration nds32_query_command_handlers[] = {
925         {
926                 .name = "target",
927                 .handler = handle_nds32_query_target_command,
928                 .mode = COMMAND_EXEC,
929                 .usage = "",
930                 .help = "reply 'OCD' for gdb to identify server-side is OpenOCD",
931         },
932         {
933                 .name = "endian",
934                 .handler = handle_nds32_query_endian_command,
935                 .mode = COMMAND_EXEC,
936                 .usage = "",
937                 .help = "query target endian",
938         },
939         {
940                 .name = "cpuid",
941                 .handler = handle_nds32_query_cpuid_command,
942                 .mode = COMMAND_EXEC,
943                 .usage = "",
944                 .help = "query CPU ID",
945         },
946
947         COMMAND_REGISTRATION_DONE
948 };
949
950 static const struct command_registration nds32_exec_command_handlers[] = {
951         {
952                 .name = "dssim",
953                 .handler = handle_nds32_dssim_command,
954                 .mode = COMMAND_EXEC,
955                 .usage = "['on'|'off']",
956                 .help = "display/change $INT_MASK.DSSIM status",
957         },
958         {
959                 .name = "mem_access",
960                 .handler = handle_nds32_memory_access_command,
961                 .mode = COMMAND_EXEC,
962                 .usage = "['bus'|'cpu']",
963                 .help = "display/change memory access channel",
964         },
965         {
966                 .name = "mem_mode",
967                 .handler = handle_nds32_memory_mode_command,
968                 .mode = COMMAND_EXEC,
969                 .usage = "['auto'|'mem'|'ilm'|'dlm']",
970                 .help = "display/change memory mode",
971         },
972         {
973                 .name = "cache",
974                 .handler = handle_nds32_cache_command,
975                 .mode = COMMAND_EXEC,
976                 .usage = "['invalidate']",
977                 .help = "cache control",
978         },
979         {
980                 .name = "icache",
981                 .handler = handle_nds32_icache_command,
982                 .mode = COMMAND_EXEC,
983                 .usage = "['invalidate'|'enable'|'disable'|'dump']",
984                 .help = "icache control",
985         },
986         {
987                 .name = "dcache",
988                 .handler = handle_nds32_dcache_command,
989                 .mode = COMMAND_EXEC,
990                 .usage = "['invalidate'|'enable'|'disable'|'dump']",
991                 .help = "dcache control",
992         },
993         {
994                 .name = "auto_break",
995                 .handler = handle_nds32_auto_break_command,
996                 .mode = COMMAND_EXEC,
997                 .usage = "['on'|'off']",
998                 .help = "convert software breakpoints to hardware breakpoints if needed",
999         },
1000         {
1001                 .name = "virtual_hosting",
1002                 .handler = handle_nds32_virtual_hosting_command,
1003                 .mode = COMMAND_ANY,
1004                 .usage = "['on'|'off']",
1005                 .help = "turn on/off virtual hosting",
1006         },
1007         {
1008                 .name = "global_stop",
1009                 .handler = handle_nds32_global_stop_command,
1010                 .mode = COMMAND_ANY,
1011                 .usage = "['on'|'off']",
1012                 .help = "turn on/off global stop. After turning on, every load/store" \
1013                          "instructions will be stopped to check memory access.",
1014         },
1015         {
1016                 .name = "soft_reset_halt",
1017                 .handler = handle_nds32_soft_reset_halt_command,
1018                 .mode = COMMAND_ANY,
1019                 .usage = "['on'|'off']",
1020                 .help = "as issuing rest-halt, to use soft-reset-halt or not." \
1021                          "the feature is for backward-compatible.",
1022         },
1023         {
1024                 .name = "boot_time",
1025                 .handler = handle_nds32_boot_time_command,
1026                 .mode = COMMAND_CONFIG,
1027                 .usage = "milliseconds",
1028                 .help = "set the period to wait after srst.",
1029         },
1030         {
1031                 .name = "login_edm_passcode",
1032                 .handler = handle_nds32_login_edm_passcode_command,
1033                 .mode = COMMAND_CONFIG,
1034                 .usage = "passcode",
1035                 .help = "set EDM passcode for secure MCU debugging.",
1036         },
1037         {
1038                 .name = "login_edm_operation",
1039                 .handler = handle_nds32_login_edm_operation_command,
1040                 .mode = COMMAND_CONFIG,
1041                 .usage = "login_edm_operation misc_reg_no value",
1042                 .help = "add EDM operations for secure MCU debugging.",
1043         },
1044         {
1045                 .name = "reset_halt_as_init",
1046                 .handler = handle_nds32_reset_halt_as_init_command,
1047                 .mode = COMMAND_CONFIG,
1048                 .usage = "['on'|'off']",
1049                 .help = "reset halt as openocd init.",
1050         },
1051         {
1052                 .name = "keep_target_edm_ctl",
1053                 .handler = handle_nds32_keep_target_edm_ctl_command,
1054                 .mode = COMMAND_CONFIG,
1055                 .usage = "['on'|'off']",
1056                 .help = "Backup/Restore target EDM_CTL register.",
1057         },
1058         {
1059                 .name = "decode",
1060                 .handler = handle_nds32_decode_command,
1061                 .mode = COMMAND_EXEC,
1062                 .usage = "address icount",
1063                 .help = "decode instruction.",
1064         },
1065         {
1066                 .name = "word_access_mem",
1067                 .handler = handle_nds32_word_access_mem_command,
1068                 .mode = COMMAND_ANY,
1069                 .usage = "['on'|'off']",
1070                 .help = "Always use word-aligned address to access memory.",
1071         },
1072         {
1073                 .name = "bulk_write",
1074                 .jim_handler = jim_nds32_bulk_write,
1075                 .mode = COMMAND_EXEC,
1076                 .help = "Write multiple 32-bit words to target memory",
1077                 .usage = "address count data",
1078         },
1079         {
1080                 .name = "multi_write",
1081                 .jim_handler = jim_nds32_multi_write,
1082                 .mode = COMMAND_EXEC,
1083                 .help = "Write multiple addresses/words to target memory",
1084                 .usage = "num_of_pairs [address data]+",
1085         },
1086         {
1087                 .name = "bulk_read",
1088                 .jim_handler = jim_nds32_bulk_read,
1089                 .mode = COMMAND_EXEC,
1090                 .help = "Read multiple 32-bit words from target memory",
1091                 .usage = "address count",
1092         },
1093         {
1094                 .name = "read_edmsr",
1095                 .jim_handler = jim_nds32_read_edm_sr,
1096                 .mode = COMMAND_EXEC,
1097                 .help = "Read EDM system register",
1098                 .usage = "['edmsw'|'edm_dtr']",
1099         },
1100         {
1101                 .name = "write_edmsr",
1102                 .jim_handler = jim_nds32_write_edm_sr,
1103                 .mode = COMMAND_EXEC,
1104                 .help = "Write EDM system register",
1105                 .usage = "['edm_dtr'] value",
1106         },
1107         {
1108                 .name = "query",
1109                 .mode = COMMAND_EXEC,
1110                 .help = "Andes query command group",
1111                 .usage = "",
1112                 .chain = nds32_query_command_handlers,
1113         },
1114
1115         COMMAND_REGISTRATION_DONE
1116 };
1117
1118 const struct command_registration nds32_command_handlers[] = {
1119         {
1120                 .name = "nds",
1121                 .mode = COMMAND_ANY,
1122                 .help = "Andes command group",
1123                 .usage = "",
1124                 .chain = nds32_exec_command_handlers,
1125         },
1126         COMMAND_REGISTRATION_DONE
1127 };
1128