xref: /openbmc/u-boot/common/bedbug.c (revision a562e1bd)
1 /* $Id$ */
2 
3 #include <common.h>
4 
5 #if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
6 
7 #include <linux/ctype.h>
8 #include <bedbug/bedbug.h>
9 #include <bedbug/ppc.h>
10 #include <bedbug/regs.h>
11 #include <bedbug/tables.h>
12 
13 #define Elf32_Word	unsigned long
14 
15 /* USE_SOURCE_CODE enables some symbolic debugging functions of this
16    code.  This is only useful if the program will have access to the
17    source code for the binary being examined.
18 */
19 
20 /* #define USE_SOURCE_CODE 1 */
21 
22 #ifdef USE_SOURCE_CODE
23 extern int line_info_from_addr __P ((Elf32_Word, char *, char *, int *));
24 extern struct symreflist *symByAddr;
25 extern char *symbol_name_from_addr __P ((Elf32_Word, int, int *));
26 #endif /* USE_SOURCE_CODE */
27 
28 int print_operands __P ((struct ppc_ctx *));
29 int get_operand_value __P ((struct opcode *, unsigned long,
30 				enum OP_FIELD, unsigned long *));
31 struct opcode *find_opcode __P ((unsigned long));
32 struct opcode *find_opcode_by_name __P ((char *));
33 char *spr_name __P ((int));
34 int spr_value __P ((char *));
35 char *tbr_name __P ((int));
36 int tbr_value __P ((char *));
37 int parse_operand __P ((unsigned long, struct opcode *,
38 			struct operand *, char *, int *));
39 int get_word __P ((char **, char *));
40 long read_number __P ((char *));
41 int downstring __P ((char *));
42 
43 
44 /*======================================================================
45  * Entry point for the PPC disassembler.
46  *
47  * Arguments:
48  *	memaddr		The address to start disassembling from.
49  *
50  *	virtual		If this value is non-zero, then this will be
51  *			used as the base address for the output and
52  *			symbol lookups.  If this value is zero then
53  *			memaddr is used as the absolute address.
54  *
55  *	num_instr	The number of instructions to disassemble.  Since
56  *			each instruction is 32 bits long, this can be
57  *			computed if you know the total size of the region.
58  *
59  *	pfunc		The address of a function that is called to print
60  *			each line of output.  The function should take a
61  *			single character pointer as its parameters a la puts.
62  *
63  *	flags		Sets options for the output.  This is a
64  *			bitwise-inclusive-OR of the following
65  *			values.  Note that only one of the radix
66  *			options may be set.
67  *
68  *			F_RADOCTAL	- output radix is unsigned base 8.
69  *			F_RADUDECIMAL	- output radix is unsigned base 10.
70  *			F_RADSDECIMAL	- output radix is signed base 10.
71  *			F_RADHEX	- output radix is unsigned base 16.
72  *			F_SIMPLE	- use simplified mnemonics.
73  *			F_SYMBOL	- lookup symbols for addresses.
74  *			F_INSTR		- output raw instruction.
75  *			F_LINENO	- show line # info if available.
76  *
77  * Returns TRUE if the area was successfully disassembled or FALSE if
78  * a problem was encountered with accessing the memory.
79  */
80 
81 int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr,
82 			int (*pfunc) (const char *), unsigned long flags)
83 {
84 	int i;
85 	struct ppc_ctx ctx;
86 
87 #ifdef USE_SOURCE_CODE
88 	int line_no = 0;
89 	int last_line_no = 0;
90 	char funcname[128] = { 0 };
91 	char filename[256] = { 0 };
92 	char last_funcname[128] = { 0 };
93 	int symoffset;
94 	char *symname;
95 	char *cursym = (char *) 0;
96 #endif /* USE_SOURCE_CODE */
97   /*------------------------------------------------------------*/
98 
99 	ctx.flags = flags;
100 	ctx.virtual = virtual;
101 
102 	/* Figure out the output radix before we go any further */
103 
104 	if (ctx.flags & F_RADOCTAL) {
105 		/* Unsigned octal output */
106 		strcpy (ctx.radix_fmt, "O%o");
107 	} else if (ctx.flags & F_RADUDECIMAL) {
108 		/* Unsigned decimal output */
109 		strcpy (ctx.radix_fmt, "%u");
110 	} else if (ctx.flags & F_RADSDECIMAL) {
111 		/* Signed decimal output */
112 		strcpy (ctx.radix_fmt, "%d");
113 	} else {
114 		/* Unsigned hex output */
115 		strcpy (ctx.radix_fmt, "0x%x");
116 	}
117 
118 	if (ctx.virtual == 0) {
119 		ctx.virtual = memaddr;
120 	}
121 #ifdef USE_SOURCE_CODE
122 	if (ctx.flags & F_SYMBOL) {
123 		if (symByAddr == 0)		/* no symbols loaded */
124 			ctx.flags &= ~F_SYMBOL;
125 		else {
126 			cursym = (char *) 0;
127 			symoffset = 0;
128 		}
129 	}
130 #endif /* USE_SOURCE_CODE */
131 
132 	/* format each line as "XXXXXXXX: <symbol> IIIIIIII  disassembly" where,
133 	   XXXXXXXX is the memory address in hex,
134 	   <symbol> is the symbolic location if F_SYMBOL is set.
135 	   IIIIIIII is the raw machine code in hex if F_INSTR is set,
136 	   and disassembly is the disassembled machine code with numbers
137 	   formatted according to the 'radix' parameter */
138 
139 	for (i = 0; i < num_instr; ++i, memaddr += 4, ctx.virtual += 4) {
140 #ifdef USE_SOURCE_CODE
141 		if (ctx.flags & F_LINENO) {
142 			if ((line_info_from_addr ((Elf32_Word) ctx.virtual, filename,
143 									  funcname, &line_no) == TRUE) &&
144 				((line_no != last_line_no) ||
145 				 (strcmp (last_funcname, funcname) != 0))) {
146 				print_source_line (filename, funcname, line_no, pfunc);
147 			}
148 			last_line_no = line_no;
149 			strcpy (last_funcname, funcname);
150 		}
151 #endif /* USE_SOURCE_CODE */
152 
153 		sprintf (ctx.data, "%08lx: ", (unsigned long) ctx.virtual);
154 		ctx.datalen = 10;
155 
156 #ifdef USE_SOURCE_CODE
157 		if (ctx.flags & F_SYMBOL) {
158 			if ((symname =
159 				 symbol_name_from_addr ((Elf32_Word) ctx.virtual,
160 										TRUE, 0)) != 0) {
161 				cursym = symname;
162 				symoffset = 0;
163 			} else {
164 				if ((cursym == 0) &&
165 					((symname =
166 					  symbol_name_from_addr ((Elf32_Word) ctx.virtual,
167 											 FALSE, &symoffset)) != 0)) {
168 					cursym = symname;
169 				} else {
170 					symoffset += 4;
171 				}
172 			}
173 
174 			if (cursym != 0) {
175 				sprintf (&ctx.data[ctx.datalen], "<%s+", cursym);
176 				ctx.datalen = strlen (ctx.data);
177 				sprintf (&ctx.data[ctx.datalen], ctx.radix_fmt, symoffset);
178 				strcat (ctx.data, ">");
179 				ctx.datalen = strlen (ctx.data);
180 			}
181 		}
182 #endif /* USE_SOURCE_CODE */
183 
184 		ctx.instr = INSTRUCTION (memaddr);
185 
186 		if (ctx.flags & F_INSTR) {
187 			/* Find the opcode structure for this opcode.  If one is not found
188 			   then it must be an illegal instruction */
189 			sprintf (&ctx.data[ctx.datalen],
190 					 "   %02lx %02lx %02lx %02lx    ",
191 					 ((ctx.instr >> 24) & 0xff),
192 					 ((ctx.instr >> 16) & 0xff), ((ctx.instr >> 8) & 0xff),
193 					 (ctx.instr & 0xff));
194 			ctx.datalen += 18;
195 		} else {
196 			strcat (ctx.data, "   ");
197 			ctx.datalen += 3;
198 		}
199 
200 		if ((ctx.op = find_opcode (ctx.instr)) == 0) {
201 			/* Illegal Opcode */
202 			sprintf (&ctx.data[ctx.datalen], "        .long 0x%08lx",
203 					 ctx.instr);
204 			ctx.datalen += 24;
205 			(*pfunc) (ctx.data);
206 			continue;
207 		}
208 
209 		if (((ctx.flags & F_SIMPLE) == 0) ||
210 			(ctx.op->hfunc == 0) || ((*ctx.op->hfunc) (&ctx) == FALSE)) {
211 			sprintf (&ctx.data[ctx.datalen], "%-7s ", ctx.op->name);
212 			ctx.datalen += 8;
213 			print_operands (&ctx);
214 		}
215 
216 		(*pfunc) (ctx.data);
217 	}
218 
219 	return TRUE;
220 }								/* disppc */
221 
222 
223 
224 /*======================================================================
225  * Called by the disassembler to print the operands for an instruction.
226  *
227  * Arguments:
228  *	ctx		A pointer to the disassembler context record.
229  *
230  * always returns 0.
231  */
232 
233 int print_operands (struct ppc_ctx *ctx)
234 {
235 	int open_parens = 0;
236 	int field;
237 	unsigned long operand;
238 	struct operand *opr;
239 
240 #ifdef USE_SOURCE_CODE
241 	char *symname;
242 	int offset;
243 #endif /* USE_SOURCE_CODE */
244   /*------------------------------------------------------------*/
245 
246 	/* Walk through the operands and list each in order */
247 	for (field = 0; ctx->op->fields[field] != 0; ++field) {
248 		if (ctx->op->fields[field] > n_operands) {
249 			continue;			/* bad operand ?! */
250 		}
251 
252 		opr = &operands[ctx->op->fields[field] - 1];
253 
254 		if (opr->hint & OH_SILENT) {
255 			continue;
256 		}
257 
258 		if ((field > 0) && !open_parens) {
259 			strcat (ctx->data, ",");
260 			ctx->datalen++;
261 		}
262 
263 		operand = (ctx->instr >> opr->shift) & ((1 << opr->bits) - 1);
264 
265 		if (opr->hint & OH_ADDR) {
266 			if ((operand & (1 << (opr->bits - 1))) != 0) {
267 				operand = operand - (1 << opr->bits);
268 			}
269 
270 			if (ctx->op->hint & H_RELATIVE)
271 				operand = (operand << 2) + (unsigned long) ctx->virtual;
272 			else
273 				operand = (operand << 2);
274 
275 
276 			sprintf (&ctx->data[ctx->datalen], "0x%lx", operand);
277 			ctx->datalen = strlen (ctx->data);
278 
279 #ifdef USE_SOURCE_CODE
280 			if ((ctx->flags & F_SYMBOL) &&
281 				((symname =
282 				  symbol_name_from_addr (operand, 0, &offset)) != 0)) {
283 				sprintf (&ctx->data[ctx->datalen], " <%s", symname);
284 				if (offset != 0) {
285 					strcat (ctx->data, "+");
286 					ctx->datalen = strlen (ctx->data);
287 					sprintf (&ctx->data[ctx->datalen], ctx->radix_fmt,
288 							 offset);
289 				}
290 				strcat (ctx->data, ">");
291 			}
292 #endif /* USE_SOURCE_CODE */
293 		}
294 
295 		else if (opr->hint & OH_REG) {
296 			if ((operand == 0) &&
297 				(opr->field == O_rA) && (ctx->op->hint & H_RA0_IS_0)) {
298 				strcat (ctx->data, "0");
299 			} else {
300 				sprintf (&ctx->data[ctx->datalen], "r%d", (short) operand);
301 			}
302 
303 			if (open_parens) {
304 				strcat (ctx->data, ")");
305 				open_parens--;
306 			}
307 		}
308 
309 		else if (opr->hint & OH_SPR) {
310 			strcat (ctx->data, spr_name (operand));
311 		}
312 
313 		else if (opr->hint & OH_TBR) {
314 			strcat (ctx->data, tbr_name (operand));
315 		}
316 
317 		else if (opr->hint & OH_LITERAL) {
318 			switch (opr->field) {
319 			case O_cr2:
320 				strcat (ctx->data, "cr2");
321 				ctx->datalen += 3;
322 				break;
323 
324 			default:
325 				break;
326 			}
327 		}
328 
329 		else {
330 			sprintf (&ctx->data[ctx->datalen], ctx->radix_fmt,
331 					 (unsigned short) operand);
332 
333 			if (open_parens) {
334 				strcat (ctx->data, ")");
335 				open_parens--;
336 			}
337 
338 			else if (opr->hint & OH_OFFSET) {
339 				strcat (ctx->data, "(");
340 				open_parens++;
341 			}
342 		}
343 
344 		ctx->datalen = strlen (ctx->data);
345 	}
346 
347 	return 0;
348 }								/* print_operands */
349 
350 
351 
352 /*======================================================================
353  * Called to get the value of an arbitrary operand with in an instruction.
354  *
355  * Arguments:
356  *	op		The pointer to the opcode structure to which
357  *			the operands belong.
358  *
359  *	instr		The instruction (32 bits) containing the opcode
360  *			and the operands to print.  By the time that
361  *			this routine is called the operand has already
362  *			been added to the output.
363  *
364  *	field		The field (operand) to get the value of.
365  *
366  *	value		The address of an unsigned long to be filled in
367  *			with the value of the operand if it is found.  This
368  *			will only be filled in if the function returns
369  *			TRUE.  This may be passed as 0 if the value is
370  *			not required.
371  *
372  * Returns TRUE if the operand was found or FALSE if it was not.
373  */
374 
375 int get_operand_value (struct opcode *op, unsigned long instr,
376 					   enum OP_FIELD field, unsigned long *value)
377 {
378 	int i;
379 	struct operand *opr;
380 
381   /*------------------------------------------------------------*/
382 
383 	if (field > n_operands) {
384 		return FALSE;			/* bad operand ?! */
385 	}
386 
387 	/* Walk through the operands and list each in order */
388 	for (i = 0; op->fields[i] != 0; ++i) {
389 		if (op->fields[i] != field) {
390 			continue;
391 		}
392 
393 		opr = &operands[op->fields[i] - 1];
394 
395 		if (value) {
396 			*value = (instr >> opr->shift) & ((1 << opr->bits) - 1);
397 		}
398 		return TRUE;
399 	}
400 
401 	return FALSE;
402 }								/* operand_value */
403 
404 
405 
406 /*======================================================================
407  * Called by the disassembler to match an opcode value to an opcode structure.
408  *
409  * Arguments:
410  *	instr		The instruction (32 bits) to match.  This value
411  *			may contain operand values as well as the opcode
412  *			since they will be masked out anyway for this
413  *			search.
414  *
415  * Returns the address of an opcode struct (from the opcode table) if the
416  * operand successfully matched an entry, or 0 if no match was found.
417  */
418 
419 struct opcode *find_opcode (unsigned long instr)
420 {
421 	struct opcode *ptr;
422 	int top = 0;
423 	int bottom = n_opcodes - 1;
424 	int idx;
425 
426   /*------------------------------------------------------------*/
427 
428 	while (top <= bottom) {
429 		idx = (top + bottom) >> 1;
430 		ptr = &opcodes[idx];
431 
432 		if ((instr & ptr->mask) < ptr->opcode) {
433 			bottom = idx - 1;
434 		} else if ((instr & ptr->mask) > ptr->opcode) {
435 			top = idx + 1;
436 		} else {
437 			return ptr;
438 		}
439 	}
440 
441 	return (struct opcode *) 0;
442 }								/* find_opcode */
443 
444 
445 
446 /*======================================================================
447  * Called by the assembler to match an opcode name to an opcode structure.
448  *
449  * Arguments:
450  *	name		The text name of the opcode, e.g. "b", "mtspr", etc.
451  *
452  * The opcodes are sorted numerically by their instruction binary code
453  * so a search for the name cannot use the binary search used by the
454  * other find routine.
455  *
456  * Returns the address of an opcode struct (from the opcode table) if the
457  * name successfully matched an entry, or 0 if no match was found.
458  */
459 
460 struct opcode *find_opcode_by_name (char *name)
461 {
462 	int idx;
463 
464   /*------------------------------------------------------------*/
465 
466 	downstring (name);
467 
468 	for (idx = 0; idx < n_opcodes; ++idx) {
469 		if (!strcmp (name, opcodes[idx].name))
470 			return &opcodes[idx];
471 	}
472 
473 	return (struct opcode *) 0;
474 }								/* find_opcode_by_name */
475 
476 
477 
478 /*======================================================================
479  * Convert the 'spr' operand from its numeric value to its symbolic name.
480  *
481  * Arguments:
482  *	value		The value of the 'spr' operand.  This value should
483  *			be unmodified from its encoding in the instruction.
484  *			the split-field computations will be performed
485  *			here before the switch.
486  *
487  * Returns the address of a character array containing the name of the
488  * special purpose register defined by the 'value' parameter, or the
489  * address of a character array containing "???" if no match was found.
490  */
491 
492 char *spr_name (int value)
493 {
494 	unsigned short spr;
495 	static char other[10];
496 	int i;
497 
498   /*------------------------------------------------------------*/
499 
500 	/* spr is a 10 bit field whose interpretation has the high and low
501 	   five-bit fields reversed from their encoding in the operand */
502 
503 	spr = ((value >> 5) & 0x1f) | ((value & 0x1f) << 5);
504 
505 	for (i = 0; i < n_sprs; ++i) {
506 		if (spr == spr_map[i].spr_val)
507 			return spr_map[i].spr_name;
508 	}
509 
510 	sprintf (other, "%d", spr);
511 	return other;
512 }								/* spr_name */
513 
514 
515 
516 /*======================================================================
517  * Convert the 'spr' operand from its symbolic name to its numeric value
518  *
519  * Arguments:
520  *	name		The symbolic name of the 'spr' operand.  The
521  *			split-field encoding will be done by this routine.
522  *			NOTE: name can be a number.
523  *
524  * Returns the numeric value for the spr appropriate for encoding a machine
525  * instruction.  Returns 0 if unable to find the SPR.
526  */
527 
528 int spr_value (char *name)
529 {
530 	struct spr_info *sprp;
531 	int spr;
532 	int i;
533 
534   /*------------------------------------------------------------*/
535 
536 	if (!name || !*name)
537 		return 0;
538 
539 	if (isdigit ((int) name[0])) {
540 		i = htonl (read_number (name));
541 		spr = ((i >> 5) & 0x1f) | ((i & 0x1f) << 5);
542 		return spr;
543 	}
544 
545 	downstring (name);
546 
547 	for (i = 0; i < n_sprs; ++i) {
548 		sprp = &spr_map[i];
549 
550 		if (strcmp (name, sprp->spr_name) == 0) {
551 			/* spr is a 10 bit field whose interpretation has the high and low
552 			   five-bit fields reversed from their encoding in the operand */
553 			i = htonl (sprp->spr_val);
554 			spr = ((i >> 5) & 0x1f) | ((i & 0x1f) << 5);
555 
556 			return spr;
557 		}
558 	}
559 
560 	return 0;
561 }								/* spr_value */
562 
563 
564 
565 /*======================================================================
566  * Convert the 'tbr' operand from its numeric value to its symbolic name.
567  *
568  * Arguments:
569  *	value		The value of the 'tbr' operand.  This value should
570  *			be unmodified from its encoding in the instruction.
571  *			the split-field computations will be performed
572  *			here before the switch.
573  *
574  * Returns the address of a character array containing the name of the
575  * time base register defined by the 'value' parameter, or the address
576  * of a character array containing "???" if no match was found.
577  */
578 
579 char *tbr_name (int value)
580 {
581 	unsigned short tbr;
582 
583   /*------------------------------------------------------------*/
584 
585 	/* tbr is a 10 bit field whose interpretation has the high and low
586 	   five-bit fields reversed from their encoding in the operand */
587 
588 	tbr = ((value >> 5) & 0x1f) | ((value & 0x1f) << 5);
589 
590 	if (tbr == 268)
591 		return "TBL";
592 
593 	else if (tbr == 269)
594 		return "TBU";
595 
596 
597 	return "???";
598 }								/* tbr_name */
599 
600 
601 
602 /*======================================================================
603  * Convert the 'tbr' operand from its symbolic name to its numeric value.
604  *
605  * Arguments:
606  *	name		The symbolic name of the 'tbr' operand.  The
607  *			split-field encoding will be done by this routine.
608  *
609  * Returns the numeric value for the spr appropriate for encoding a machine
610  * instruction.  Returns 0 if unable to find the TBR.
611  */
612 
613 int tbr_value (char *name)
614 {
615 	int tbr;
616 	int val;
617 
618   /*------------------------------------------------------------*/
619 
620 	if (!name || !*name)
621 		return 0;
622 
623 	downstring (name);
624 
625 	if (isdigit ((int) name[0])) {
626 		val = read_number (name);
627 
628 		if (val != 268 && val != 269)
629 			return 0;
630 	} else if (strcmp (name, "tbl") == 0)
631 		val = 268;
632 	else if (strcmp (name, "tbu") == 0)
633 		val = 269;
634 	else
635 		return 0;
636 
637 	/* tbr is a 10 bit field whose interpretation has the high and low
638 	   five-bit fields reversed from their encoding in the operand */
639 
640 	val = htonl (val);
641 	tbr = ((val >> 5) & 0x1f) | ((val & 0x1f) << 5);
642 	return tbr;
643 }								/* tbr_name */
644 
645 
646 
647 /*======================================================================
648  * The next several functions (handle_xxx) are the routines that handle
649  * disassembling the opcodes with simplified mnemonics.
650  *
651  * Arguments:
652  *	ctx		A pointer to the disassembler context record.
653  *
654  * Returns TRUE if the simpler form was printed or FALSE if it was not.
655  */
656 
657 int handle_bc (struct ppc_ctx *ctx)
658 {
659 	unsigned long bo;
660 	unsigned long bi;
661 	static struct opcode blt = { B_OPCODE (16, 0, 0), B_MASK, {O_BD, 0},
662 	0, "blt", H_RELATIVE
663 	};
664 	static struct opcode bne =
665 			{ B_OPCODE (16, 0, 0), B_MASK, {O_cr2, O_BD, 0},
666 	0, "bne", H_RELATIVE
667 	};
668 	static struct opcode bdnz = { B_OPCODE (16, 0, 0), B_MASK, {O_BD, 0},
669 	0, "bdnz", H_RELATIVE
670 	};
671 
672   /*------------------------------------------------------------*/
673 
674 	if (get_operand_value (ctx->op, ctx->instr, O_BO, &bo) == FALSE)
675 		return FALSE;
676 
677 	if (get_operand_value (ctx->op, ctx->instr, O_BI, &bi) == FALSE)
678 		return FALSE;
679 
680 	if ((bo == 12) && (bi == 0)) {
681 		ctx->op = &blt;
682 		sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
683 		ctx->datalen += 8;
684 		print_operands (ctx);
685 		return TRUE;
686 	} else if ((bo == 4) && (bi == 10)) {
687 		ctx->op = &bne;
688 		sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
689 		ctx->datalen += 8;
690 		print_operands (ctx);
691 		return TRUE;
692 	} else if ((bo == 16) && (bi == 0)) {
693 		ctx->op = &bdnz;
694 		sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
695 		ctx->datalen += 8;
696 		print_operands (ctx);
697 		return TRUE;
698 	}
699 
700 	return FALSE;
701 }								/* handle_blt */
702 
703 
704 
705 /*======================================================================
706  * Outputs source line information for the disassembler.  This should
707  * be modified in the future to lookup the actual line of source code
708  * from the file, but for now this will do.
709  *
710  * Arguments:
711  *	filename	The address of a character array containing the
712  *			absolute path and file name of the source file.
713  *
714  *	funcname	The address of a character array containing the
715  *			name of the function (not C++ demangled (yet))
716  *			to which this code belongs.
717  *
718  *	line_no		An integer specifying the source line number that
719  *			generated this code.
720  *
721  *	pfunc		The address of a function to call to print the output.
722  *
723  *
724  * Returns TRUE if it was able to output the line info, or false if it was
725  * not.
726  */
727 
728 int print_source_line (char *filename, char *funcname,
729 					   int line_no, int (*pfunc) (const char *))
730 {
731 	char out_buf[256];
732 
733   /*------------------------------------------------------------*/
734 
735 	(*pfunc) ("");				/* output a newline */
736 	sprintf (out_buf, "%s %s(): line %d", filename, funcname, line_no);
737 	(*pfunc) (out_buf);
738 
739 	return TRUE;
740 }								/* print_source_line */
741 
742 
743 
744 /*======================================================================
745  * Entry point for the PPC assembler.
746  *
747  * Arguments:
748  *	asm_buf		An array of characters containing the assembly opcode
749  *			and operands to convert to a POWERPC machine
750  *			instruction.
751  *
752  * Returns the machine instruction or zero.
753  */
754 
755 unsigned long asmppc (unsigned long memaddr, char *asm_buf, int *err)
756 {
757 	struct opcode *opc;
758 	struct operand *oper[MAX_OPERANDS];
759 	unsigned long instr;
760 	unsigned long param;
761 	char *ptr = asm_buf;
762 	char scratch[20];
763 	int i;
764 	int w_operands = 0;			/* wanted # of operands */
765 	int n_operands = 0;			/* # of operands read */
766 	int asm_debug = 0;
767 
768   /*------------------------------------------------------------*/
769 
770 	if (err)
771 		*err = 0;
772 
773 	if (get_word (&ptr, scratch) == 0)
774 		return 0;
775 
776 	/* Lookup the opcode structure based on the opcode name */
777 	if ((opc = find_opcode_by_name (scratch)) == (struct opcode *) 0) {
778 		if (err)
779 			*err = E_ASM_BAD_OPCODE;
780 		return 0;
781 	}
782 
783 	if (asm_debug) {
784 		printf ("asmppc: Opcode = \"%s\"\n", opc->name);
785 	}
786 
787 	for (i = 0; i < 8; ++i) {
788 		if (opc->fields[i] == 0)
789 			break;
790 		++w_operands;
791 	}
792 
793 	if (asm_debug) {
794 		printf ("asmppc: Expecting %d operands\n", w_operands);
795 	}
796 
797 	instr = opc->opcode;
798 
799 	/* read each operand */
800 	while (n_operands < w_operands) {
801 
802 		oper[n_operands] = &operands[opc->fields[n_operands] - 1];
803 
804 		if (oper[n_operands]->hint & OH_SILENT) {
805 			/* Skip silent operands, they are covered in opc->opcode */
806 
807 			if (asm_debug) {
808 				printf ("asmppc: Operand %d \"%s\" SILENT\n", n_operands,
809 						oper[n_operands]->name);
810 			}
811 
812 			++n_operands;
813 			continue;
814 		}
815 
816 		if (get_word (&ptr, scratch) == 0)
817 			break;
818 
819 		if (asm_debug) {
820 			printf ("asmppc: Operand %d \"%s\" : \"%s\"\n", n_operands,
821 					oper[n_operands]->name, scratch);
822 		}
823 
824 		if ((param = parse_operand (memaddr, opc, oper[n_operands],
825 									scratch, err)) == -1)
826 			return 0;
827 
828 		instr |= param;
829 		++n_operands;
830 	}
831 
832 	if (n_operands < w_operands) {
833 		if (err)
834 			*err = E_ASM_NUM_OPERANDS;
835 		return 0;
836 	}
837 
838 	if (asm_debug) {
839 		printf ("asmppc: Instruction = 0x%08lx\n", instr);
840 	}
841 
842 	return instr;
843 }								/* asmppc */
844 
845 
846 
847 /*======================================================================
848  * Called by the assembler to interpret a single operand
849  *
850  * Arguments:
851  *	ctx		A pointer to the disassembler context record.
852  *
853  * Returns 0 if the operand is ok, or -1 if it is bad.
854  */
855 
856 int parse_operand (unsigned long memaddr, struct opcode *opc,
857 				   struct operand *oper, char *txt, int *err)
858 {
859 	long data;
860 	long mask;
861 	int is_neg = 0;
862 
863   /*------------------------------------------------------------*/
864 
865 	mask = (1 << oper->bits) - 1;
866 
867 	if (oper->hint & OH_ADDR) {
868 		data = read_number (txt);
869 
870 		if (opc->hint & H_RELATIVE)
871 			data = data - memaddr;
872 
873 		if (data < 0)
874 			is_neg = 1;
875 
876 		data >>= 2;
877 		data &= (mask >> 1);
878 
879 		if (is_neg)
880 			data |= 1 << (oper->bits - 1);
881 	}
882 
883 	else if (oper->hint & OH_REG) {
884 		if (txt[0] == 'r' || txt[0] == 'R')
885 			txt++;
886 		else if (txt[0] == '%' && (txt[1] == 'r' || txt[1] == 'R'))
887 			txt += 2;
888 
889 		data = read_number (txt);
890 		if (data > 31) {
891 			if (err)
892 				*err = E_ASM_BAD_REGISTER;
893 			return -1;
894 		}
895 
896 		data = htonl (data);
897 	}
898 
899 	else if (oper->hint & OH_SPR) {
900 		if ((data = spr_value (txt)) == 0) {
901 			if (err)
902 				*err = E_ASM_BAD_SPR;
903 			return -1;
904 		}
905 	}
906 
907 	else if (oper->hint & OH_TBR) {
908 		if ((data = tbr_value (txt)) == 0) {
909 			if (err)
910 				*err = E_ASM_BAD_TBR;
911 			return -1;
912 		}
913 	}
914 
915 	else {
916 		data = htonl (read_number (txt));
917 	}
918 
919 	return (data & mask) << oper->shift;
920 }								/* parse_operand */
921 
922 
923 char *asm_error_str (int err)
924 {
925 	switch (err) {
926 	case E_ASM_BAD_OPCODE:
927 		return "Bad opcode";
928 	case E_ASM_NUM_OPERANDS:
929 		return "Bad number of operands";
930 	case E_ASM_BAD_REGISTER:
931 		return "Bad register number";
932 	case E_ASM_BAD_SPR:
933 		return "Bad SPR name or number";
934 	case E_ASM_BAD_TBR:
935 		return "Bad TBR name or number";
936 	}
937 
938 	return "";
939 }								/* asm_error_str */
940 
941 
942 
943 /*======================================================================
944  * Copy a word from one buffer to another, ignores leading white spaces.
945  *
946  * Arguments:
947  *	src		The address of a character pointer to the
948  *			source buffer.
949  *	dest		A pointer to a character buffer to write the word
950  *			into.
951  *
952  * Returns the number of non-white space characters copied, or zero.
953  */
954 
955 int get_word (char **src, char *dest)
956 {
957 	char *ptr = *src;
958 	int nchars = 0;
959 
960   /*------------------------------------------------------------*/
961 
962 	/* Eat white spaces */
963 	while (*ptr && isblank (*ptr))
964 		ptr++;
965 
966 	if (*ptr == 0) {
967 		*src = ptr;
968 		return 0;
969 	}
970 
971 	/* Find the text of the word */
972 	while (*ptr && !isblank (*ptr) && (*ptr != ','))
973 		dest[nchars++] = *ptr++;
974 	ptr = (*ptr == ',') ? ptr + 1 : ptr;
975 	dest[nchars] = 0;
976 
977 	*src = ptr;
978 	return nchars;
979 }								/* get_word */
980 
981 
982 
983 /*======================================================================
984  * Convert a numeric string to a number, be aware of base notations.
985  *
986  * Arguments:
987  *	txt		The numeric string.
988  *
989  * Returns the converted numeric value.
990  */
991 
992 long read_number (char *txt)
993 {
994 	long val;
995 	int is_neg = 0;
996 
997   /*------------------------------------------------------------*/
998 
999 	if (txt == 0 || *txt == 0)
1000 		return 0;
1001 
1002 	if (*txt == '-') {
1003 		is_neg = 1;
1004 		++txt;
1005 	}
1006 
1007 	if (txt[0] == '0' && (txt[1] == 'x' || txt[1] == 'X'))	/* hex */
1008 		val = simple_strtoul (&txt[2], NULL, 16);
1009 	else						/* decimal */
1010 		val = simple_strtoul (txt, NULL, 10);
1011 
1012 	if (is_neg)
1013 		val = -val;
1014 
1015 	return val;
1016 }								/* read_number */
1017 
1018 
1019 int downstring (char *s)
1020 {
1021 	if (!s || !*s)
1022 		return 0;
1023 
1024 	while (*s) {
1025 		if (isupper (*s))
1026 			*s = tolower (*s);
1027 		s++;
1028 	}
1029 
1030 	return 0;
1031 }								/* downstring */
1032 
1033 
1034 
1035 /*======================================================================
1036  * Examines the instruction at the current address and determines the
1037  * next address to be executed.  This will take into account branches
1038  * of different types so that a "step" and "next" operations can be
1039  * supported.
1040  *
1041  * Arguments:
1042  *	nextaddr	The address (to be filled in) of the next
1043  *			instruction to execute.  This will only be a valid
1044  *			address if TRUE is returned.
1045  *
1046  *	step_over	A flag indicating how to compute addresses for
1047  *			branch statements:
1048  *			 TRUE  = Step over the branch (next)
1049  *			 FALSE = step into the branch (step)
1050  *
1051  * Returns TRUE if it was able to compute the address.  Returns FALSE if
1052  * it has a problem reading the current instruction or one of the registers.
1053  */
1054 
1055 int find_next_address (unsigned char *nextaddr, int step_over,
1056 					   struct pt_regs *regs)
1057 {
1058 	unsigned long pc;			/* SRR0 register from PPC */
1059 	unsigned long ctr;			/* CTR register from PPC */
1060 	unsigned long cr;			/* CR register from PPC */
1061 	unsigned long lr;			/* LR register from PPC */
1062 	unsigned long instr;		/* instruction at SRR0 */
1063 	unsigned long next;			/* computed instruction for 'next' */
1064 	unsigned long step;			/* computed instruction for 'step' */
1065 	unsigned long addr = 0;		/* target address operand */
1066 	unsigned long aa = 0;		/* AA operand */
1067 	unsigned long lk = 0;		/* LK operand */
1068 	unsigned long bo = 0;		/* BO operand */
1069 	unsigned long bi = 0;		/* BI operand */
1070 	struct opcode *op = 0;		/* opcode structure for 'instr' */
1071 	int ctr_ok = 0;
1072 	int cond_ok = 0;
1073 	int conditional = 0;
1074 	int branch = 0;
1075 
1076   /*------------------------------------------------------------*/
1077 
1078 	if (nextaddr == 0 || regs == 0) {
1079 		printf ("find_next_address: bad args");
1080 		return FALSE;
1081 	}
1082 
1083 	pc = regs->nip & 0xfffffffc;
1084 	instr = INSTRUCTION (pc);
1085 
1086 	if ((op = find_opcode (instr)) == (struct opcode *) 0) {
1087 		printf ("find_next_address: can't parse opcode 0x%lx", instr);
1088 		return FALSE;
1089 	}
1090 
1091 	ctr = regs->ctr;
1092 	cr = regs->ccr;
1093 	lr = regs->link;
1094 
1095 	switch (op->opcode) {
1096 	case B_OPCODE (16, 0, 0):	/* bc */
1097 	case B_OPCODE (16, 0, 1):	/* bcl */
1098 	case B_OPCODE (16, 1, 0):	/* bca */
1099 	case B_OPCODE (16, 1, 1):	/* bcla */
1100 		if (!get_operand_value (op, instr, O_BD, &addr) ||
1101 			!get_operand_value (op, instr, O_BO, &bo) ||
1102 			!get_operand_value (op, instr, O_BI, &bi) ||
1103 			!get_operand_value (op, instr, O_AA, &aa) ||
1104 			!get_operand_value (op, instr, O_LK, &lk))
1105 			return FALSE;
1106 
1107 		if ((addr & (1 << 13)) != 0)
1108 			addr = addr - (1 << 14);
1109 		addr <<= 2;
1110 		conditional = 1;
1111 		branch = 1;
1112 		break;
1113 
1114 	case I_OPCODE (18, 0, 0):	/* b */
1115 	case I_OPCODE (18, 0, 1):	/* bl */
1116 	case I_OPCODE (18, 1, 0):	/* ba */
1117 	case I_OPCODE (18, 1, 1):	/* bla */
1118 		if (!get_operand_value (op, instr, O_LI, &addr) ||
1119 			!get_operand_value (op, instr, O_AA, &aa) ||
1120 			!get_operand_value (op, instr, O_LK, &lk))
1121 			return FALSE;
1122 
1123 		if ((addr & (1 << 23)) != 0)
1124 			addr = addr - (1 << 24);
1125 		addr <<= 2;
1126 		conditional = 0;
1127 		branch = 1;
1128 		break;
1129 
1130 	case XL_OPCODE (19, 528, 0):	/* bcctr */
1131 	case XL_OPCODE (19, 528, 1):	/* bcctrl */
1132 		if (!get_operand_value (op, instr, O_BO, &bo) ||
1133 			!get_operand_value (op, instr, O_BI, &bi) ||
1134 			!get_operand_value (op, instr, O_LK, &lk))
1135 			return FALSE;
1136 
1137 		addr = ctr;
1138 		aa = 1;
1139 		conditional = 1;
1140 		branch = 1;
1141 		break;
1142 
1143 	case XL_OPCODE (19, 16, 0):	/* bclr */
1144 	case XL_OPCODE (19, 16, 1):	/* bclrl */
1145 		if (!get_operand_value (op, instr, O_BO, &bo) ||
1146 			!get_operand_value (op, instr, O_BI, &bi) ||
1147 			!get_operand_value (op, instr, O_LK, &lk))
1148 			return FALSE;
1149 
1150 		addr = lr;
1151 		aa = 1;
1152 		conditional = 1;
1153 		branch = 1;
1154 		break;
1155 
1156 	default:
1157 		conditional = 0;
1158 		branch = 0;
1159 		break;
1160 	}
1161 
1162 	if (conditional) {
1163 		switch ((bo & 0x1e) >> 1) {
1164 		case 0:				/* 0000y */
1165 			if (--ctr != 0)
1166 				ctr_ok = 1;
1167 
1168 			cond_ok = !(cr & (1 << (31 - bi)));
1169 			break;
1170 
1171 		case 1:				/* 0001y */
1172 			if (--ctr == 0)
1173 				ctr_ok = 1;
1174 
1175 			cond_ok = !(cr & (1 << (31 - bi)));
1176 			break;
1177 
1178 		case 2:				/* 001zy */
1179 			ctr_ok = 1;
1180 			cond_ok = !(cr & (1 << (31 - bi)));
1181 			break;
1182 
1183 		case 4:				/* 0100y */
1184 			if (--ctr != 0)
1185 				ctr_ok = 1;
1186 
1187 			cond_ok = cr & (1 << (31 - bi));
1188 			break;
1189 
1190 		case 5:				/* 0101y */
1191 			if (--ctr == 0)
1192 				ctr_ok = 1;
1193 
1194 			cond_ok = cr & (1 << (31 - bi));
1195 			break;
1196 
1197 		case 6:				/* 011zy */
1198 			ctr_ok = 1;
1199 			cond_ok = cr & (1 << (31 - bi));
1200 			break;
1201 
1202 		case 8:				/* 1z00y */
1203 			if (--ctr != 0)
1204 				ctr_ok = cond_ok = 1;
1205 			break;
1206 
1207 		case 9:				/* 1z01y */
1208 			if (--ctr == 0)
1209 				ctr_ok = cond_ok = 1;
1210 			break;
1211 
1212 		case 10:				/* 1z1zz */
1213 			ctr_ok = cond_ok = 1;
1214 			break;
1215 		}
1216 	}
1217 
1218 	if (branch && (!conditional || (ctr_ok && cond_ok))) {
1219 		if (aa)
1220 			step = addr;
1221 		else
1222 			step = addr + pc;
1223 
1224 		if (lk)
1225 			next = pc + 4;
1226 		else
1227 			next = step;
1228 	} else {
1229 		step = next = pc + 4;
1230 	}
1231 
1232 	if (step_over == TRUE)
1233 		*(unsigned long *) nextaddr = next;
1234 	else
1235 		*(unsigned long *) nextaddr = step;
1236 
1237 	return TRUE;
1238 }								/* find_next_address */
1239 
1240 
1241 /*
1242  * Copyright (c) 2000 William L. Pitts and W. Gerald Hicks
1243  * All rights reserved.
1244  *
1245  * Redistribution and use in source and binary forms are freely
1246  * permitted provided that the above copyright notice and this
1247  * paragraph and the following disclaimer are duplicated in all
1248  * such forms.
1249  *
1250  * This software is provided "AS IS" and without any express or
1251  * implied warranties, including, without limitation, the implied
1252  * warranties of merchantability and fitness for a particular
1253  * purpose.
1254  */
1255 
1256 #endif	/* CONFIG_COMMANDS & CFG_CMD_BEDBUG */
1257