1 /* MSPDebug - debugging tool for the eZ430
2  * Copyright (C) 2009, 2010 Daniel Beer
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <ctype.h>
23 #include <unistd.h>
24 
25 #include "device.h"
26 #include "binfile.h"
27 #include "stab.h"
28 #include "expr.h"
29 #include "reader.h"
30 #include "output_util.h"
31 #include "util.h"
32 #include "prog.h"
33 #include "dis.h"
34 #include "opdb.h"
35 
cmd_regs(char ** arg)36 int cmd_regs(char **arg)
37 {
38 	address_t regs[DEVICE_NUM_REGS];
39 	uint8_t code[16];
40 	int len = sizeof(code);
41 	int i;
42 
43 	(void)arg;
44 
45 	if (device_getregs(regs) < 0)
46 		return -1;
47 
48 	/* Check for breakpoints */
49 	for (i = 0; i < device_default->max_breakpoints; i++) {
50 		const struct device_breakpoint *bp =
51 		    &device_default->breakpoints[i];
52 
53 		if ((bp->flags & DEVICE_BP_ENABLED) &&
54 		    (bp->type == DEVICE_BPTYPE_BREAK) &&
55 		    (bp->addr == regs[MSP430_REG_PC]))
56 			printc("Breakpoint %d triggered (0x%04x)\n",
57 				i, bp->addr);
58 	}
59 
60 	show_regs(regs);
61 
62 	/* Try to disassemble the instruction at PC */
63 	if (len > 0x10000 - regs[0])
64 		len = 0x10000 - regs[0];
65 	if (device_readmem(regs[0], code, len) < 0)
66 		return 0;
67 
68 	disassemble(regs[0], (uint8_t *)code, len, device_default->power_buf);
69 	return 0;
70 }
71 
cmd_md(char ** arg)72 int cmd_md(char **arg)
73 {
74 	char *off_text = get_arg(arg);
75 	char *len_text = get_arg(arg);
76 	address_t offset = 0;
77 	address_t length = 0x40;
78 
79 	if (!off_text) {
80 		printc_err("md: offset must be specified\n");
81 		return -1;
82 	}
83 
84 	if (expr_eval(off_text, &offset) < 0) {
85 		printc_err("md: can't parse offset: %s\n", off_text);
86 		return -1;
87 	}
88 
89 	if (len_text) {
90 		if (expr_eval(len_text, &length) < 0) {
91 			printc_err("md: can't parse length: %s\n",
92 				len_text);
93 			return -1;
94 		}
95 	} else if (offset < 0x10000 && offset + length > 0x10000) {
96 		length = 0x10000 - offset;
97 	}
98 
99 	reader_set_repeat("md 0x%x 0x%x", offset + length, length);
100 
101 	while (length) {
102 		uint8_t buf[4096];
103 		int blen = length > sizeof(buf) ? sizeof(buf) : length;
104 
105 		if (device_readmem(offset, buf, blen) < 0)
106 			return -1;
107 		hexdump(offset, buf, blen);
108 
109 		offset += blen;
110 		length -= blen;
111 	}
112 
113 	return 0;
114 }
115 
cmd_mw(char ** arg)116 int cmd_mw(char **arg)
117 {
118 	char *off_text = get_arg(arg);
119 	char *byte_text;
120 	address_t offset = 0;
121 	address_t length = 0;
122 	uint8_t buf[1024];
123 
124 	if (!off_text) {
125 		printc_err("md: offset must be specified\n");
126 		return -1;
127 	}
128 
129 	if (expr_eval(off_text, &offset) < 0) {
130 		printc_err("md: can't parse offset: %s\n", off_text);
131 		return -1;
132 	}
133 
134 	while ((byte_text = get_arg(arg))) {
135 		if (length >= sizeof(buf)) {
136 			printc_err("md: maximum length exceeded\n");
137 			return -1;
138 		}
139 
140 		buf[length++] = strtoul(byte_text, NULL, 16);
141 	}
142 
143 	if (!length)
144 		return 0;
145 
146 	if (device_writemem(offset, buf, length) < 0)
147 		return -1;
148 
149 	return 0;
150 }
151 
cmd_reset(char ** arg)152 int cmd_reset(char **arg)
153 {
154 	(void)arg;
155 
156 	return device_ctl(DEVICE_CTL_RESET);
157 }
158 
cmd_erase(char ** arg)159 int cmd_erase(char **arg)
160 {
161 	const char *type_text = get_arg(arg);
162 	const char *seg_text = get_arg(arg);
163 	device_erase_type_t type = DEVICE_ERASE_MAIN;
164 	address_t segment = 0;
165 	address_t total_size = 0;
166 	address_t segment_size = 0;
167 
168 	if (seg_text && expr_eval(seg_text, &segment) < 0) {
169 		printc_err("erase: invalid expression: %s\n", seg_text);
170 		return -1;
171 	}
172 
173 	if (type_text) {
174 		if (!strcasecmp(type_text, "all")) {
175 			type = DEVICE_ERASE_ALL;
176 		} else if (!strcasecmp(type_text, "segment")) {
177 			type = DEVICE_ERASE_SEGMENT;
178 			if (!seg_text) {
179 				printc_err("erase: expected segment "
180 					   "address\n");
181 				return -1;
182 			}
183 		} else if (!strcasecmp(type_text, "segrange")) {
184 			const char *total_text = get_arg(arg);
185 			const char *ss_text = get_arg(arg);
186 
187 			if (!(total_text && ss_text)) {
188 				printc_err("erase: you must specify "
189 					   "total and segment sizes\n");
190 				return -1;
191 			}
192 
193 			if (expr_eval(total_text, &total_size) < 0) {
194 				printc_err("erase: invalid expression: %s\n",
195 					   total_text);
196 				return -1;
197 			}
198 
199 			if (expr_eval(ss_text, &segment_size) < 0) {
200 				printc_err("erase: invalid expression: %s\n",
201 					   ss_text);
202 				return -1;
203 			}
204 
205 			if (segment_size > 0x200 || segment_size < 0x40) {
206 				printc_err("erase: invalid segment size: "
207 					   "0x%x\n", segment_size);
208 				return -1;
209 			}
210 		} else {
211 			printc_err("erase: unknown erase type: %s\n",
212 				    type_text);
213 			return -1;
214 		}
215 	}
216 
217 	if (device_ctl(DEVICE_CTL_HALT) < 0)
218 		return -1;
219 
220 	if (!segment_size) {
221 		printc("Erasing...\n");
222 		return device_erase(type, segment);
223 	} else {
224 		printc("Erasing segments...\n");
225 		while (total_size >= segment_size) {
226 			printc_dbg("Erasing 0x%04x...\n", segment);
227 			if (device_erase(DEVICE_ERASE_SEGMENT, segment) < 0)
228 				return -1;
229 			total_size -= segment_size;
230 			segment += segment_size;
231 		}
232 	}
233 
234 	return 0;
235 }
236 
bp_poll(void)237 static int bp_poll(void)
238 {
239 	address_t regs[DEVICE_NUM_REGS];
240 	int i;
241 
242 	if (device_getregs(regs) < 0)
243 		return -1;
244 
245 	for (i = 0; i < device_default->max_breakpoints; i++) {
246 		const struct device_breakpoint *bp =
247 		    &device_default->breakpoints[i];
248 
249 		if ((bp->flags & DEVICE_BP_ENABLED) &&
250 		    (bp->type == DEVICE_BPTYPE_BREAK) &&
251 		    (bp->addr == regs[MSP430_REG_PC]))
252 			return 1;
253 	}
254 
255 	return 0;
256 }
257 
cmd_step(char ** arg)258 int cmd_step(char **arg)
259 {
260 	char *count_text = get_arg(arg);
261 	address_t count = 1;
262 	int i;
263 
264 	if (count_text) {
265 		if (expr_eval(count_text, &count) < 0) {
266 			printc_err("step: can't parse count: %s\n", count_text);
267 			return -1;
268 		}
269 	}
270 
271 	for (i = 0; i < count; i++) {
272 		int r;
273 
274 		if (device_ctl(DEVICE_CTL_STEP) < 0)
275 			return -1;
276 
277 		r = bp_poll();
278 
279 		if (r < 0)
280 			return -1;
281 
282 		if (r) {
283 			printc("Breakpoint hit after %d steps\n", i + 1);
284 			break;
285 		}
286 	}
287 
288 	reader_set_repeat("step");
289 	return cmd_regs(NULL);
290 }
291 
cmd_run(char ** arg)292 int cmd_run(char **arg)
293 {
294 	device_status_t status;
295 	address_t regs[DEVICE_NUM_REGS];
296 
297 	(void)arg;
298 
299 	if (device_getregs(regs) < 0) {
300 		printc_err("warning: device: can't fetch registers\n");
301 	} else {
302 		int i;
303 
304 		for (i = 0; i < device_default->max_breakpoints; i++) {
305 			struct device_breakpoint *bp =
306 				&device_default->breakpoints[i];
307 
308 			if ((bp->flags & DEVICE_BP_ENABLED) &&
309 			    bp->type == DEVICE_BPTYPE_BREAK &&
310 			    bp->addr == regs[0])
311 				break;
312 		}
313 
314 		if (i < device_default->max_breakpoints) {
315 			printc("Stepping over breakpoint #%d at 0x%04x\n",
316 			       i, regs[0]);
317 			device_ctl(DEVICE_CTL_STEP);
318 		}
319 	}
320 
321 	if (device_ctl(DEVICE_CTL_RUN) < 0) {
322 		printc_err("run: failed to start CPU\n");
323 		return -1;
324 	}
325 
326 	printc("Running. Press Ctrl+C to interrupt...\n");
327 
328 	do {
329 		status = device_poll();
330 	} while (status == DEVICE_STATUS_RUNNING);
331 
332 	if (status == DEVICE_STATUS_INTR)
333 		printc("\n");
334 
335 	if (status == DEVICE_STATUS_ERROR)
336 		return -1;
337 
338 	if (device_ctl(DEVICE_CTL_HALT) < 0)
339 		return -1;
340 
341 	return cmd_regs(NULL);
342 }
343 
cmd_set(char ** arg)344 int cmd_set(char **arg)
345 {
346 	char *reg_text = get_arg(arg);
347 	char *val_text = get_arg(arg);
348 	int reg;
349 	address_t value = 0;
350 	address_t regs[DEVICE_NUM_REGS];
351 
352 	if (!(reg_text && val_text)) {
353 		printc_err("set: must specify a register and a value\n");
354 		return -1;
355 	}
356 
357 	reg = dis_reg_from_name(reg_text);
358 	if (reg < 0) {
359 		printc_err("set: unknown register: %s\n", reg_text);
360 		return -1;
361 	}
362 
363 	if (expr_eval(val_text, &value) < 0) {
364 		printc_err("set: can't parse value: %s\n", val_text);
365 		return -1;
366 	}
367 
368 	if (device_getregs(regs) < 0)
369 		return -1;
370 	regs[reg] = value;
371 	if (device_setregs(regs) < 0)
372 		return -1;
373 
374 	show_regs(regs);
375 	return 0;
376 }
377 
cmd_dis(char ** arg)378 int cmd_dis(char **arg)
379 {
380 	char *off_text = get_arg(arg);
381 	char *len_text = get_arg(arg);
382 	address_t offset = 0;
383 	address_t length = 0x40;
384 	uint8_t *buf;
385 
386 	if (!off_text) {
387 		printc_err("dis: offset must be specified\n");
388 		return -1;
389 	}
390 
391 	if (expr_eval(off_text, &offset) < 0) {
392 		printc_err("dis: can't parse offset: %s\n", off_text);
393 		return -1;
394 	}
395 
396 	if (len_text) {
397 		if (expr_eval(len_text, &length) < 0) {
398 			printc_err("dis: can't parse length: %s\n",
399 				len_text);
400 			return -1;
401 		}
402 	}
403 	length += (length & 1);
404 	if (offset < 0x10000 && offset + length > 0x10000) {
405 		length = 0x10000 - offset;
406 	}
407 
408 	buf = malloc(length);
409 	if (!buf) {
410 		pr_error("dis: couldn't allocate memory");
411 		return -1;
412 	}
413 
414 	if (device_readmem(offset, buf, length) < 0) {
415 		free(buf);
416 		return -1;
417 	}
418 
419 	offset = disassemble(offset, buf, length, device_default->power_buf);
420 	reader_set_repeat("dis 0x%x 0x%x", offset, length);
421 	free(buf);
422 	return 0;
423 }
424 
425 
426 #define IHEX_REC_DATA 0x00
427 #define IHEX_REC_EOF  0x01
428 #define IHEX_REC_ESAR 0x02
429 #define IHEX_REC_SSAR 0x03
430 #define IHEX_REC_ELAR 0x04
431 #define IHEX_REC_SLAR 0x05
432 #define IHEX_SEG(addr) (((addr) >> 16) & 0xFFFF)
433 
434 struct hexout_data {
435 	FILE            *file;
436 	address_t       addr;
437 	uint8_t         buf[16];
438 	int             len;
439 
440 	uint16_t        segoff;
441 };
442 
hexout_start(struct hexout_data * hexout,const char * filename)443 static int hexout_start(struct hexout_data *hexout, const char *filename)
444 {
445 	char * path = NULL;
446 
447 	path = expand_tilde(filename);
448 	if (!path)
449 		return -1;
450 
451 	hexout->file = fopen(path, "w");
452 	free(path);
453 
454 	if (!hexout->file) {
455 		pr_error("hexout: couldn't open output file");
456 		return -1;
457 	}
458 
459 	hexout->addr = 0;
460 	hexout->len = 0;
461 	hexout->segoff = 0;
462 
463 	return 0;
464 }
465 
hexout_write(FILE * out,uint8_t type,int len,uint16_t addr,const uint8_t * payload)466 static int hexout_write(FILE *out, uint8_t type, int len, uint16_t addr,
467 			const uint8_t *payload)
468 {
469 	int i;
470 	int cksum = 0;
471 
472 	if (fprintf(out, ":%02X%04X%02X", len, addr, type) < 0)
473 		goto fail;
474 	cksum += len;
475 	cksum += addr & 0xff;
476 	cksum += addr >> 8;
477 	cksum += type;
478 
479 	for (i = 0; i < len; i++) {
480 		if (fprintf(out, "%02X", payload[i]) < 0)
481 			goto fail;
482 		cksum += payload[i];
483 	}
484 
485 	if (fprintf(out, "%02X\n", ~(cksum - 1) & 0xff) < 0)
486 		goto fail;
487 
488 	return 0;
489 
490 fail:
491 	pr_error("hexout: can't write HEX data");
492 	return -1;
493 }
494 
hexout_flush(struct hexout_data * hexout)495 static int hexout_flush(struct hexout_data *hexout)
496 {
497 	while (hexout->len) {
498 		address_t addr_low = hexout->addr & 0xffff;
499 		address_t segoff = IHEX_SEG(hexout->addr);
500 
501 		if (segoff != hexout->segoff) {
502 			uint8_t offset_data[] = {segoff >> 8, segoff & 0xff};
503 
504 			if (hexout_write(hexout->file, IHEX_REC_ELAR,
505 				2, 0, offset_data) < 0)
506 				return -1;
507 			hexout->segoff = segoff;
508 		}
509 
510 		uint32_t writesize = hexout->len;
511 
512 		/* If the hexout buffer will wrap past the end of segment;
513 		 * only write until the end of the segment to allow
514 		 * emitting an ELAR record */
515 		if (IHEX_SEG(hexout->addr + writesize) != segoff)
516 			writesize = 0x10000 - addr_low;
517 
518 		if (hexout_write(hexout->file, IHEX_REC_DATA, writesize, addr_low,
519 				hexout->buf) < 0)
520 			return -1;
521 
522 		hexout->len -= writesize;
523 		hexout->addr += writesize;
524 
525 		memmove(hexout->buf, hexout->buf + writesize,
526 			sizeof(hexout->buf) - writesize);
527 	}
528 
529 	return 0;
530 }
531 
hexout_feed(struct hexout_data * hexout,uint32_t addr,const uint8_t * buf,int len)532 static int hexout_feed(struct hexout_data *hexout,
533 		       uint32_t addr, const uint8_t *buf, int len)
534 {
535 	while (len) {
536 		int count;
537 
538 		if ((hexout->addr + hexout->len != addr ||
539 		     hexout->len >= sizeof(hexout->buf)) &&
540 		    hexout_flush(hexout) < 0)
541 			return -1;
542 
543 		if (!hexout->len)
544 			hexout->addr = addr;
545 
546 		count = sizeof(hexout->buf) - hexout->len;
547 		if (count > len)
548 			count = len;
549 
550 		memcpy(hexout->buf + hexout->len, buf, count);
551 		hexout->len += count;
552 
553 		addr += count;
554 		buf += count;
555 		len -= count;
556 	}
557 
558 	return 0;
559 }
560 
cmd_hexout(char ** arg)561 int cmd_hexout(char **arg)
562 {
563 	char *off_text = get_arg(arg);
564 	char *len_text = get_arg(arg);
565 	char *filename = *arg;
566 	address_t off;
567 	address_t length;
568 	struct hexout_data hexout;
569 
570 	if (!(off_text && len_text && *filename)) {
571 		printc_err("hexout: need offset, length and filename\n");
572 		return -1;
573 	}
574 
575 	if (expr_eval(off_text, &off) < 0 ||
576 	    expr_eval(len_text, &length) < 0)
577 		return -1;
578 
579 	if (hexout_start(&hexout, filename) < 0)
580 		return -1;
581 
582 	while (length) {
583 		uint8_t buf[4096];
584 		int count = length;
585 
586 		if (count > sizeof(buf))
587 			count = sizeof(buf);
588 
589 		printc("Reading %4d bytes from 0x%04x...\n", count, off);
590 		if (device_readmem(off, buf, count) < 0) {
591 			pr_error("hexout: can't read memory");
592 			goto fail;
593 		}
594 
595 		if (hexout_feed(&hexout, off, buf, count) < 0)
596 			goto fail;
597 
598 		length -= count;
599 		off += count;
600 	}
601 
602 	if (hexout_flush(&hexout) < 0)
603 		goto fail;
604 
605 	if (hexout_write(hexout.file, IHEX_REC_EOF, 0, 0, NULL) < 0) {
606 		pr_error("hexout: failed to write terminator\n");
607 		goto fail;
608 	}
609 
610 	if (fclose(hexout.file) < 0) {
611 		pr_error("hexout: error on close");
612 		return -1;
613 	}
614 
615 	return 0;
616 
617 fail:
618 	fclose(hexout.file);
619 	unlink(filename);
620 	return -1;
621 }
622 
cmd_prog_feed(void * user_data,const struct binfile_chunk * ch)623 static int cmd_prog_feed(void *user_data, const struct binfile_chunk *ch)
624 {
625 	return prog_feed((struct prog_data *)user_data, ch);
626 }
627 
do_cmd_prog(char ** arg,int prog_flags)628 static int do_cmd_prog(char **arg, int prog_flags)
629 {
630 	FILE *in;
631 	struct prog_data prog;
632 	const char *path_arg;
633 	char * path;
634 
635 	path_arg = get_arg(arg);
636 	if (!path_arg) {
637 		printc_err("prog: you need to specify a filename\n");
638 		return -1;
639 	}
640 
641 	if (prompt_abort(MODIFY_SYMS))
642 		return 0;
643 
644 	path = expand_tilde(path_arg);
645 	if (!path)
646 		return -1;
647 
648 	in = fopen(path, "rb");
649 	if (!in) {
650 		printc_err("prog: %s: %s\n", path, last_error());
651                 free(path);
652 		return -1;
653 	}
654 	free(path);
655 
656 	if (device_ctl(DEVICE_CTL_HALT) < 0) {
657 		fclose(in);
658 		return -1;
659 	}
660 
661 	prog_init(&prog, prog_flags);
662 
663 	if (binfile_extract(in, cmd_prog_feed, &prog) < 0) {
664 		fclose(in);
665 		return -1;
666 	}
667 
668 	if ((prog_flags & PROG_WANT_ERASE) &&
669 	    (binfile_info(in) & BINFILE_HAS_SYMS)) {
670 		stab_clear();
671 		binfile_syms(in);
672 	}
673 
674 	fclose(in);
675 
676 	if (prog_flush(&prog) < 0)
677 		return -1;
678 
679 	printc("Done, %d bytes total\n", prog.total_written);
680 
681 	if (device_ctl(DEVICE_CTL_RESET) < 0)
682 		printc_err("warning: prog: "
683 			   "failed to reset after programming\n");
684 
685 	unmark_modified(MODIFY_SYMS);
686 	return 0;
687 }
688 
cmd_prog(char ** arg)689 int cmd_prog(char **arg)
690 {
691 	return do_cmd_prog(arg, PROG_WANT_ERASE);
692 }
693 
cmd_load(char ** arg)694 int cmd_load(char **arg)
695 {
696 	return do_cmd_prog(arg, 0);
697 }
698 
cmd_verify(char ** arg)699 int cmd_verify(char **arg)
700 {
701 	return do_cmd_prog(arg, PROG_VERIFY);
702 }
703 
do_setbreak(device_bptype_t type,char ** arg)704 static int do_setbreak(device_bptype_t type, char **arg)
705 {
706 	char *addr_text = get_arg(arg);
707 	char *index_text = get_arg(arg);
708 	int index = -1;
709 	address_t addr;
710 
711 	if (!addr_text) {
712 		printc_err("setbreak: address required\n");
713 		return -1;
714 	}
715 
716 	if (expr_eval(addr_text, &addr) < 0) {
717 		printc_err("setbreak: invalid address\n");
718 		return -1;
719 	}
720 
721 	if (index_text) {
722 		address_t val;
723 
724 		if (expr_eval(index_text, &val) < 0 ||
725 		    val >= device_default->max_breakpoints) {
726 			printc("setbreak: invalid breakpoint slot: %d\n",
727 			       val);
728 			return -1;
729 		}
730 
731 		index = val;
732 	}
733 
734 	index = device_setbrk(device_default, index, 1, addr, type);
735 	if (index < 0) {
736 		printc_err("setbreak: all breakpoint slots are "
737 			"occupied\n");
738 		return -1;
739 	}
740 
741 	printc("Set breakpoint %d\n", index);
742 	return 0;
743 }
744 
cmd_setbreak(char ** arg)745 int cmd_setbreak(char **arg)
746 {
747 	return do_setbreak(DEVICE_BPTYPE_BREAK, arg);
748 }
749 
cmd_setwatch(char ** arg)750 int cmd_setwatch(char **arg)
751 {
752 	return do_setbreak(DEVICE_BPTYPE_WATCH, arg);
753 }
754 
cmd_setwatch_w(char ** arg)755 int cmd_setwatch_w(char **arg)
756 {
757 	return do_setbreak(DEVICE_BPTYPE_WRITE, arg);
758 }
759 
cmd_setwatch_r(char ** arg)760 int cmd_setwatch_r(char **arg)
761 {
762 	return do_setbreak(DEVICE_BPTYPE_READ, arg);
763 }
764 
cmd_delbreak(char ** arg)765 int cmd_delbreak(char **arg)
766 {
767 	char *index_text = get_arg(arg);
768 	int ret = 0;
769 
770 	if (index_text) {
771 		address_t index;
772 
773 		if (expr_eval(index_text, &index) < 0 ||
774 		    index >= device_default->max_breakpoints) {
775 			printc("delbreak: invalid breakpoint slot: %d\n",
776 			       index);
777 			return -1;
778 		}
779 
780 		printc("Clearing breakpoint %d\n", index);
781 		device_setbrk(device_default, index, 0, 0, 0);
782 	} else {
783 		int i;
784 
785 		printc("Clearing all breakpoints...\n");
786 		for (i = 0; i < device_default->max_breakpoints; i++)
787 			device_setbrk(device_default, i, 0, 0, 0);
788 	}
789 
790 	return ret;
791 }
792 
cmd_break(char ** arg)793 int cmd_break(char **arg)
794 {
795 	int i;
796 
797 	(void)arg;
798 
799 	printc("%d breakpoints available:\n",
800 	       device_default->max_breakpoints);
801 	for (i = 0; i < device_default->max_breakpoints; i++) {
802 		const struct device_breakpoint *bp =
803 			&device_default->breakpoints[i];
804 
805 		if (bp->flags & DEVICE_BP_ENABLED) {
806 			char name[128];
807 
808 			print_address(bp->addr, name, sizeof(name), 0);
809 			printc("    %d. %s", i, name);
810 
811 			switch (bp->type) {
812 			case DEVICE_BPTYPE_WATCH:
813 				printc(" [watchpoint]\n");
814 				break;
815 
816 			case DEVICE_BPTYPE_READ:
817 				printc(" [read watchpoint]\n");
818 				break;
819 
820 			case DEVICE_BPTYPE_WRITE:
821 				printc(" [write watchpoint]\n");
822 				break;
823 
824 			case DEVICE_BPTYPE_BREAK:
825 				printc("\n");
826 				break;
827 			}
828 		}
829 	}
830 
831 	return 0;
832 }
833 
cmd_fill(char ** arg)834 int cmd_fill(char **arg)
835 {
836 	char *addr_text = get_arg(arg);
837 	char *len_text = get_arg(arg);
838 	char *byte_text;
839 	address_t addr = 0;
840 	address_t len = 0;
841 	uint8_t buf[256];
842 	int period = 0;
843 	int phase = 0;
844 	int i;
845 
846 	if (!(addr_text && len_text)) {
847 		printc_err("fill: address and length must be supplied\n");
848 		return -1;
849 	}
850 
851 	if (expr_eval(addr_text, &addr) < 0) {
852 		printc_err("fill: invalid address\n");
853 		return -1;
854 	}
855 
856 	if (expr_eval(len_text, &len) < 0) {
857 		printc_err("fill: invalid length\n");
858 		return -1;
859 	}
860 
861 	while ((byte_text = get_arg(arg))) {
862 		if (period >= sizeof(buf)) {
863 			printc_err("fill: maximum length exceeded\n");
864 			return -1;
865 		}
866 
867 		buf[period++] = strtoul(byte_text, NULL, 16);
868 	}
869 
870 	if (!period) {
871 		printc_err("fill: no pattern supplied\n");
872 		return -1;
873 	}
874 
875 	for (i = period; i < sizeof(buf); i++)
876 		buf[i] = buf[i % period];
877 
878 	while (len > 0) {
879 		int plen = sizeof(buf) - phase;
880 
881 		if (plen > len)
882 			plen = len;
883 
884 		if (device_writemem(addr, buf + phase, plen) < 0)
885 			return -1;
886 
887 		addr += plen;
888 		len -= plen;
889 		phase = (phase + plen) % period;
890 	}
891 
892 	return 0;
893 }
894 
cmd_blow_jtag_fuse(char ** arg)895 int cmd_blow_jtag_fuse(char **arg)
896 {
897 	(void)arg;
898 
899 	if (!opdb_get_boolean("enable_fuse_blow")) {
900 		printc_err(
901 "blow_jtag_fuse: fuse blow has not been enabled.\n"
902 "\n"
903 "If you really want to blow the JTAG fuse, you need to set the option\n"
904 "\"enable_fuse_blow\" first. If in doubt, do not do this.\n"
905 "\n"
906 "\x1b[1mWARNING: this is in irreversible operation!\x1b[0m\n");
907 		return -1;
908 	}
909 
910 	return device_ctl(DEVICE_CTL_SECURE);
911 }
912