MINI2440: Auto probe for SDRAM size
[u-boot-openmoko/mini2440.git] / common / bedbug.c
blob3bf1fc3cc7f06e11d20226a2640b6d4b1ddca548
1 /* $Id$ */
3 #include <common.h>
5 #if defined(CONFIG_CMD_BEDBUG)
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>
13 #define Elf32_Word unsigned long
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.
20 /* #define USE_SOURCE_CODE 1 */
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 */
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 *));
44 /*======================================================================
45 * Entry point for the PPC disassembler.
47 * Arguments:
48 * memaddr The address to start disassembling from.
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.
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.
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.
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.
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.
77 * Returns TRUE if the area was successfully disassembled or FALSE if
78 * a problem was encountered with accessing the memory.
81 int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr,
82 int (*pfunc) (const char *), unsigned long flags)
84 int i;
85 struct ppc_ctx ctx;
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 /*------------------------------------------------------------*/
99 ctx.flags = flags;
100 ctx.virtual = virtual;
102 /* Figure out the output radix before we go any further */
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");
118 if (ctx.virtual == 0) {
119 ctx.virtual = memaddr;
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;
130 #endif /* USE_SOURCE_CODE */
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 */
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);
148 last_line_no = line_no;
149 strcpy (last_funcname, funcname);
151 #endif /* USE_SOURCE_CODE */
153 sprintf (ctx.data, "%08lx: ", (unsigned long) ctx.virtual);
154 ctx.datalen = 10;
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;
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);
182 #endif /* USE_SOURCE_CODE */
184 ctx.instr = INSTRUCTION (memaddr);
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;
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;
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);
216 (*pfunc) (ctx.data);
219 return TRUE;
220 } /* disppc */
224 /*======================================================================
225 * Called by the disassembler to print the operands for an instruction.
227 * Arguments:
228 * ctx A pointer to the disassembler context record.
230 * always returns 0.
233 int print_operands (struct ppc_ctx *ctx)
235 int open_parens = 0;
236 int field;
237 unsigned long operand;
238 struct operand *opr;
240 #ifdef USE_SOURCE_CODE
241 char *symname;
242 int offset;
243 #endif /* USE_SOURCE_CODE */
244 /*------------------------------------------------------------*/
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 ?! */
252 opr = &operands[ctx->op->fields[field] - 1];
254 if (opr->hint & OH_SILENT) {
255 continue;
258 if ((field > 0) && !open_parens) {
259 strcat (ctx->data, ",");
260 ctx->datalen++;
263 operand = (ctx->instr >> opr->shift) & ((1 << opr->bits) - 1);
265 if (opr->hint & OH_ADDR) {
266 if ((operand & (1 << (opr->bits - 1))) != 0) {
267 operand = operand - (1 << opr->bits);
270 if (ctx->op->hint & H_RELATIVE)
271 operand = (operand << 2) + (unsigned long) ctx->virtual;
272 else
273 operand = (operand << 2);
276 sprintf (&ctx->data[ctx->datalen], "0x%lx", operand);
277 ctx->datalen = strlen (ctx->data);
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);
290 strcat (ctx->data, ">");
292 #endif /* USE_SOURCE_CODE */
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);
303 if (open_parens) {
304 strcat (ctx->data, ")");
305 open_parens--;
309 else if (opr->hint & OH_SPR) {
310 strcat (ctx->data, spr_name (operand));
313 else if (opr->hint & OH_TBR) {
314 strcat (ctx->data, tbr_name (operand));
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;
324 default:
325 break;
329 else {
330 sprintf (&ctx->data[ctx->datalen], ctx->radix_fmt,
331 (unsigned short) operand);
333 if (open_parens) {
334 strcat (ctx->data, ")");
335 open_parens--;
338 else if (opr->hint & OH_OFFSET) {
339 strcat (ctx->data, "(");
340 open_parens++;
344 ctx->datalen = strlen (ctx->data);
347 return 0;
348 } /* print_operands */
352 /*======================================================================
353 * Called to get the value of an arbitrary operand with in an instruction.
355 * Arguments:
356 * op The pointer to the opcode structure to which
357 * the operands belong.
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.
364 * field The field (operand) to get the value of.
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.
372 * Returns TRUE if the operand was found or FALSE if it was not.
375 int get_operand_value (struct opcode *op, unsigned long instr,
376 enum OP_FIELD field, unsigned long *value)
378 int i;
379 struct operand *opr;
381 /*------------------------------------------------------------*/
383 if (field > n_operands) {
384 return FALSE; /* bad operand ?! */
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;
393 opr = &operands[op->fields[i] - 1];
395 if (value) {
396 *value = (instr >> opr->shift) & ((1 << opr->bits) - 1);
398 return TRUE;
401 return FALSE;
402 } /* operand_value */
406 /*======================================================================
407 * Called by the disassembler to match an opcode value to an opcode structure.
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.
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.
419 struct opcode *find_opcode (unsigned long instr)
421 struct opcode *ptr;
422 int top = 0;
423 int bottom = n_opcodes - 1;
424 int idx;
426 /*------------------------------------------------------------*/
428 while (top <= bottom) {
429 idx = (top + bottom) >> 1;
430 ptr = &opcodes[idx];
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;
441 return (struct opcode *) 0;
442 } /* find_opcode */
446 /*======================================================================
447 * Called by the assembler to match an opcode name to an opcode structure.
449 * Arguments:
450 * name The text name of the opcode, e.g. "b", "mtspr", etc.
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.
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.
460 struct opcode *find_opcode_by_name (char *name)
462 int idx;
464 /*------------------------------------------------------------*/
466 downstring (name);
468 for (idx = 0; idx < n_opcodes; ++idx) {
469 if (!strcmp (name, opcodes[idx].name))
470 return &opcodes[idx];
473 return (struct opcode *) 0;
474 } /* find_opcode_by_name */
478 /*======================================================================
479 * Convert the 'spr' operand from its numeric value to its symbolic name.
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.
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.
492 char *spr_name (int value)
494 unsigned short spr;
495 static char other[10];
496 int i;
498 /*------------------------------------------------------------*/
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 */
503 spr = ((value >> 5) & 0x1f) | ((value & 0x1f) << 5);
505 for (i = 0; i < n_sprs; ++i) {
506 if (spr == spr_map[i].spr_val)
507 return spr_map[i].spr_name;
510 sprintf (other, "%d", spr);
511 return other;
512 } /* spr_name */
516 /*======================================================================
517 * Convert the 'spr' operand from its symbolic name to its numeric value
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.
524 * Returns the numeric value for the spr appropriate for encoding a machine
525 * instruction. Returns 0 if unable to find the SPR.
528 int spr_value (char *name)
530 struct spr_info *sprp;
531 int spr;
532 int i;
534 /*------------------------------------------------------------*/
536 if (!name || !*name)
537 return 0;
539 if (isdigit ((int) name[0])) {
540 i = htonl (read_number (name));
541 spr = ((i >> 5) & 0x1f) | ((i & 0x1f) << 5);
542 return spr;
545 downstring (name);
547 for (i = 0; i < n_sprs; ++i) {
548 sprp = &spr_map[i];
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);
556 return spr;
560 return 0;
561 } /* spr_value */
565 /*======================================================================
566 * Convert the 'tbr' operand from its numeric value to its symbolic name.
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.
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.
579 char *tbr_name (int value)
581 unsigned short tbr;
583 /*------------------------------------------------------------*/
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 */
588 tbr = ((value >> 5) & 0x1f) | ((value & 0x1f) << 5);
590 if (tbr == 268)
591 return "TBL";
593 else if (tbr == 269)
594 return "TBU";
597 return "???";
598 } /* tbr_name */
602 /*======================================================================
603 * Convert the 'tbr' operand from its symbolic name to its numeric value.
605 * Arguments:
606 * name The symbolic name of the 'tbr' operand. The
607 * split-field encoding will be done by this routine.
609 * Returns the numeric value for the spr appropriate for encoding a machine
610 * instruction. Returns 0 if unable to find the TBR.
613 int tbr_value (char *name)
615 int tbr;
616 int val;
618 /*------------------------------------------------------------*/
620 if (!name || !*name)
621 return 0;
623 downstring (name);
625 if (isdigit ((int) name[0])) {
626 val = read_number (name);
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;
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 */
640 val = htonl (val);
641 tbr = ((val >> 5) & 0x1f) | ((val & 0x1f) << 5);
642 return tbr;
643 } /* tbr_name */
647 /*======================================================================
648 * The next several functions (handle_xxx) are the routines that handle
649 * disassembling the opcodes with simplified mnemonics.
651 * Arguments:
652 * ctx A pointer to the disassembler context record.
654 * Returns TRUE if the simpler form was printed or FALSE if it was not.
657 int handle_bc (struct ppc_ctx *ctx)
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
664 static struct opcode bne =
665 { B_OPCODE (16, 0, 0), B_MASK, {O_cr2, O_BD, 0},
666 0, "bne", H_RELATIVE
668 static struct opcode bdnz = { B_OPCODE (16, 0, 0), B_MASK, {O_BD, 0},
669 0, "bdnz", H_RELATIVE
672 /*------------------------------------------------------------*/
674 if (get_operand_value (ctx->op, ctx->instr, O_BO, &bo) == FALSE)
675 return FALSE;
677 if (get_operand_value (ctx->op, ctx->instr, O_BI, &bi) == FALSE)
678 return FALSE;
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;
700 return FALSE;
701 } /* handle_blt */
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.
710 * Arguments:
711 * filename The address of a character array containing the
712 * absolute path and file name of the source file.
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.
718 * line_no An integer specifying the source line number that
719 * generated this code.
721 * pfunc The address of a function to call to print the output.
724 * Returns TRUE if it was able to output the line info, or false if it was
725 * not.
728 int print_source_line (char *filename, char *funcname,
729 int line_no, int (*pfunc) (const char *))
731 char out_buf[256];
733 /*------------------------------------------------------------*/
735 (*pfunc) (""); /* output a newline */
736 sprintf (out_buf, "%s %s(): line %d", filename, funcname, line_no);
737 (*pfunc) (out_buf);
739 return TRUE;
740 } /* print_source_line */
744 /*======================================================================
745 * Entry point for the PPC assembler.
747 * Arguments:
748 * asm_buf An array of characters containing the assembly opcode
749 * and operands to convert to a POWERPC machine
750 * instruction.
752 * Returns the machine instruction or zero.
755 unsigned long asmppc (unsigned long memaddr, char *asm_buf, int *err)
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;
768 /*------------------------------------------------------------*/
770 if (err)
771 *err = 0;
773 if (get_word (&ptr, scratch) == 0)
774 return 0;
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;
783 if (asm_debug) {
784 printf ("asmppc: Opcode = \"%s\"\n", opc->name);
787 for (i = 0; i < 8; ++i) {
788 if (opc->fields[i] == 0)
789 break;
790 ++w_operands;
793 if (asm_debug) {
794 printf ("asmppc: Expecting %d operands\n", w_operands);
797 instr = opc->opcode;
799 /* read each operand */
800 while (n_operands < w_operands) {
802 oper[n_operands] = &operands[opc->fields[n_operands] - 1];
804 if (oper[n_operands]->hint & OH_SILENT) {
805 /* Skip silent operands, they are covered in opc->opcode */
807 if (asm_debug) {
808 printf ("asmppc: Operand %d \"%s\" SILENT\n", n_operands,
809 oper[n_operands]->name);
812 ++n_operands;
813 continue;
816 if (get_word (&ptr, scratch) == 0)
817 break;
819 if (asm_debug) {
820 printf ("asmppc: Operand %d \"%s\" : \"%s\"\n", n_operands,
821 oper[n_operands]->name, scratch);
824 if ((param = parse_operand (memaddr, opc, oper[n_operands],
825 scratch, err)) == -1)
826 return 0;
828 instr |= param;
829 ++n_operands;
832 if (n_operands < w_operands) {
833 if (err)
834 *err = E_ASM_NUM_OPERANDS;
835 return 0;
838 if (asm_debug) {
839 printf ("asmppc: Instruction = 0x%08lx\n", instr);
842 return instr;
843 } /* asmppc */
847 /*======================================================================
848 * Called by the assembler to interpret a single operand
850 * Arguments:
851 * ctx A pointer to the disassembler context record.
853 * Returns 0 if the operand is ok, or -1 if it is bad.
856 int parse_operand (unsigned long memaddr, struct opcode *opc,
857 struct operand *oper, char *txt, int *err)
859 long data;
860 long mask;
861 int is_neg = 0;
863 /*------------------------------------------------------------*/
865 mask = (1 << oper->bits) - 1;
867 if (oper->hint & OH_ADDR) {
868 data = read_number (txt);
870 if (opc->hint & H_RELATIVE)
871 data = data - memaddr;
873 if (data < 0)
874 is_neg = 1;
876 data >>= 2;
877 data &= (mask >> 1);
879 if (is_neg)
880 data |= 1 << (oper->bits - 1);
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;
889 data = read_number (txt);
890 if (data > 31) {
891 if (err)
892 *err = E_ASM_BAD_REGISTER;
893 return -1;
896 data = htonl (data);
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;
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;
915 else {
916 data = htonl (read_number (txt));
919 return (data & mask) << oper->shift;
920 } /* parse_operand */
923 char *asm_error_str (int err)
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";
938 return "";
939 } /* asm_error_str */
943 /*======================================================================
944 * Copy a word from one buffer to another, ignores leading white spaces.
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.
952 * Returns the number of non-white space characters copied, or zero.
955 int get_word (char **src, char *dest)
957 char *ptr = *src;
958 int nchars = 0;
960 /*------------------------------------------------------------*/
962 /* Eat white spaces */
963 while (*ptr && isblank (*ptr))
964 ptr++;
966 if (*ptr == 0) {
967 *src = ptr;
968 return 0;
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;
977 *src = ptr;
978 return nchars;
979 } /* get_word */
983 /*======================================================================
984 * Convert a numeric string to a number, be aware of base notations.
986 * Arguments:
987 * txt The numeric string.
989 * Returns the converted numeric value.
992 long read_number (char *txt)
994 long val;
995 int is_neg = 0;
997 /*------------------------------------------------------------*/
999 if (txt == 0 || *txt == 0)
1000 return 0;
1002 if (*txt == '-') {
1003 is_neg = 1;
1004 ++txt;
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);
1012 if (is_neg)
1013 val = -val;
1015 return val;
1016 } /* read_number */
1019 int downstring (char *s)
1021 if (!s || !*s)
1022 return 0;
1024 while (*s) {
1025 if (isupper (*s))
1026 *s = tolower (*s);
1027 s++;
1030 return 0;
1031 } /* downstring */
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.
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.
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)
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.
1055 int find_next_address (unsigned char *nextaddr, int step_over,
1056 struct pt_regs *regs)
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;
1076 /*------------------------------------------------------------*/
1078 if (nextaddr == 0 || regs == 0) {
1079 printf ("find_next_address: bad args");
1080 return FALSE;
1083 pc = regs->nip & 0xfffffffc;
1084 instr = INSTRUCTION (pc);
1086 if ((op = find_opcode (instr)) == (struct opcode *) 0) {
1087 printf ("find_next_address: can't parse opcode 0x%lx", instr);
1088 return FALSE;
1091 ctr = regs->ctr;
1092 cr = regs->ccr;
1093 lr = regs->link;
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;
1107 if ((addr & (1 << 13)) != 0)
1108 addr = addr - (1 << 14);
1109 addr <<= 2;
1110 conditional = 1;
1111 branch = 1;
1112 break;
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;
1123 if ((addr & (1 << 23)) != 0)
1124 addr = addr - (1 << 24);
1125 addr <<= 2;
1126 conditional = 0;
1127 branch = 1;
1128 break;
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;
1137 addr = ctr;
1138 aa = 1;
1139 conditional = 1;
1140 branch = 1;
1141 break;
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;
1150 addr = lr;
1151 aa = 1;
1152 conditional = 1;
1153 branch = 1;
1154 break;
1156 default:
1157 conditional = 0;
1158 branch = 0;
1159 break;
1162 if (conditional) {
1163 switch ((bo & 0x1e) >> 1) {
1164 case 0: /* 0000y */
1165 if (--ctr != 0)
1166 ctr_ok = 1;
1168 cond_ok = !(cr & (1 << (31 - bi)));
1169 break;
1171 case 1: /* 0001y */
1172 if (--ctr == 0)
1173 ctr_ok = 1;
1175 cond_ok = !(cr & (1 << (31 - bi)));
1176 break;
1178 case 2: /* 001zy */
1179 ctr_ok = 1;
1180 cond_ok = !(cr & (1 << (31 - bi)));
1181 break;
1183 case 4: /* 0100y */
1184 if (--ctr != 0)
1185 ctr_ok = 1;
1187 cond_ok = cr & (1 << (31 - bi));
1188 break;
1190 case 5: /* 0101y */
1191 if (--ctr == 0)
1192 ctr_ok = 1;
1194 cond_ok = cr & (1 << (31 - bi));
1195 break;
1197 case 6: /* 011zy */
1198 ctr_ok = 1;
1199 cond_ok = cr & (1 << (31 - bi));
1200 break;
1202 case 8: /* 1z00y */
1203 if (--ctr != 0)
1204 ctr_ok = cond_ok = 1;
1205 break;
1207 case 9: /* 1z01y */
1208 if (--ctr == 0)
1209 ctr_ok = cond_ok = 1;
1210 break;
1212 case 10: /* 1z1zz */
1213 ctr_ok = cond_ok = 1;
1214 break;
1218 if (branch && (!conditional || (ctr_ok && cond_ok))) {
1219 if (aa)
1220 step = addr;
1221 else
1222 step = addr + pc;
1224 if (lk)
1225 next = pc + 4;
1226 else
1227 next = step;
1228 } else {
1229 step = next = pc + 4;
1232 if (step_over == TRUE)
1233 *(unsigned long *) nextaddr = next;
1234 else
1235 *(unsigned long *) nextaddr = step;
1237 return TRUE;
1238 } /* find_next_address */
1242 * Copyright (c) 2000 William L. Pitts and W. Gerald Hicks
1243 * All rights reserved.
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.
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.
1256 #endif