From 485c90c06bbb01f9ae3e5746836152ce5ea36c0f Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Sat, 1 Jan 2022 19:13:26 +0200 Subject: common: remove bedbug debugger support Commit 98f705c9cefd ("powerpc: remove 4xx support") removed (in 2017) the last code that made use of bedbug debugger support. Since there aren't any boards left that define either CONFIG_CMD_BEDBUG or a real bedbug_init(), drop this feature from u-boot. Signed-off-by: Ovidiu Panait Reviewed-by: Thomas Huth Reviewed-by: Simon Glass --- common/Makefile | 1 - common/bedbug.c | 1254 ------------------------------------------------------ common/board_r.c | 9 +- 3 files changed, 1 insertion(+), 1263 deletions(-) delete mode 100644 common/bedbug.c (limited to 'common') diff --git a/common/Makefile b/common/Makefile index 24be05c368..3eff719601 100644 --- a/common/Makefile +++ b/common/Makefile @@ -17,7 +17,6 @@ obj-y += board_r.o obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o obj-$(CONFIG_DISPLAY_BOARDINFO_LATE) += board_info.o -obj-$(CONFIG_CMD_BEDBUG) += bedbug.o obj-$(CONFIG_FDT_SIMPLEFB) += fdt_simplefb.o obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += fdt_support.o obj-$(CONFIG_MII) += miiphyutil.o diff --git a/common/bedbug.c b/common/bedbug.c deleted file mode 100644 index c76fa4898c..0000000000 --- a/common/bedbug.c +++ /dev/null @@ -1,1254 +0,0 @@ -/* $Id$ */ - -#include -#include - -#include -#include -#include -#include -#include - -#define Elf32_Word unsigned long - -/* USE_SOURCE_CODE enables some symbolic debugging functions of this - code. This is only useful if the program will have access to the - source code for the binary being examined. -*/ - -/* #define USE_SOURCE_CODE 1 */ - -#ifdef USE_SOURCE_CODE -extern int line_info_from_addr __P ((Elf32_Word, char *, char *, int *)); -extern struct symreflist *symByAddr; -extern char *symbol_name_from_addr __P ((Elf32_Word, int, int *)); -#endif /* USE_SOURCE_CODE */ - -int print_operands __P ((struct ppc_ctx *)); -int get_operand_value __P ((struct opcode *, unsigned long, - enum OP_FIELD, unsigned long *)); -struct opcode *find_opcode __P ((unsigned long)); -struct opcode *find_opcode_by_name __P ((char *)); -char *spr_name __P ((int)); -int spr_value __P ((char *)); -char *tbr_name __P ((int)); -int tbr_value __P ((char *)); -int parse_operand __P ((unsigned long, struct opcode *, - struct operand *, char *, int *)); -int get_word __P ((char **, char *)); -long read_number __P ((char *)); -int downstring __P ((char *)); - - -/*====================================================================== - * Entry point for the PPC disassembler. - * - * Arguments: - * memaddr The address to start disassembling from. - * - * virtual If this value is non-zero, then this will be - * used as the base address for the output and - * symbol lookups. If this value is zero then - * memaddr is used as the absolute address. - * - * num_instr The number of instructions to disassemble. Since - * each instruction is 32 bits long, this can be - * computed if you know the total size of the region. - * - * pfunc The address of a function that is called to print - * each line of output. The function should take a - * single character pointer as its parameters a la puts. - * - * flags Sets options for the output. This is a - * bitwise-inclusive-OR of the following - * values. Note that only one of the radix - * options may be set. - * - * F_RADOCTAL - output radix is unsigned base 8. - * F_RADUDECIMAL - output radix is unsigned base 10. - * F_RADSDECIMAL - output radix is signed base 10. - * F_RADHEX - output radix is unsigned base 16. - * F_SIMPLE - use simplified mnemonics. - * F_SYMBOL - lookup symbols for addresses. - * F_INSTR - output raw instruction. - * F_LINENO - show line # info if available. - * - * Returns true if the area was successfully disassembled or false if - * a problem was encountered with accessing the memory. - */ - -int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr, - int (*pfunc) (const char *), unsigned long flags) -{ - int i; - struct ppc_ctx ctx; - -#ifdef USE_SOURCE_CODE - int line_no = 0; - int last_line_no = 0; - char funcname[128] = { 0 }; - char filename[256] = { 0 }; - char last_funcname[128] = { 0 }; - int symoffset; - char *symname; - char *cursym = (char *) 0; -#endif /* USE_SOURCE_CODE */ - /*------------------------------------------------------------*/ - - ctx.flags = flags; - ctx.virtual = virtual; - - /* Figure out the output radix before we go any further */ - - if (ctx.flags & F_RADOCTAL) { - /* Unsigned octal output */ - strcpy (ctx.radix_fmt, "O%o"); - } else if (ctx.flags & F_RADUDECIMAL) { - /* Unsigned decimal output */ - strcpy (ctx.radix_fmt, "%u"); - } else if (ctx.flags & F_RADSDECIMAL) { - /* Signed decimal output */ - strcpy (ctx.radix_fmt, "%d"); - } else { - /* Unsigned hex output */ - strcpy (ctx.radix_fmt, "0x%x"); - } - - if (ctx.virtual == 0) { - ctx.virtual = memaddr; - } -#ifdef USE_SOURCE_CODE - if (ctx.flags & F_SYMBOL) { - if (symByAddr == 0) /* no symbols loaded */ - ctx.flags &= ~F_SYMBOL; - else { - cursym = (char *) 0; - symoffset = 0; - } - } -#endif /* USE_SOURCE_CODE */ - - /* format each line as "XXXXXXXX: IIIIIIII disassembly" where, - XXXXXXXX is the memory address in hex, - is the symbolic location if F_SYMBOL is set. - IIIIIIII is the raw machine code in hex if F_INSTR is set, - and disassembly is the disassembled machine code with numbers - formatted according to the 'radix' parameter */ - - for (i = 0; i < num_instr; ++i, memaddr += 4, ctx.virtual += 4) { -#ifdef USE_SOURCE_CODE - if (ctx.flags & F_LINENO) { - if ((line_info_from_addr ((Elf32_Word) ctx.virtual, - filename, funcname, &line_no) == true) && - ((line_no != last_line_no) || - (strcmp (last_funcname, funcname) != 0))) { - print_source_line (filename, funcname, line_no, pfunc); - } - last_line_no = line_no; - strcpy (last_funcname, funcname); - } -#endif /* USE_SOURCE_CODE */ - - sprintf (ctx.data, "%08lx: ", (unsigned long) ctx.virtual); - ctx.datalen = 10; - -#ifdef USE_SOURCE_CODE - if (ctx.flags & F_SYMBOL) { - if ((symname = - symbol_name_from_addr((Elf32_Word) ctx.virtual, - true, 0)) != 0) { - cursym = symname; - symoffset = 0; - } else { - if ((cursym == 0) && - ((symname = - symbol_name_from_addr((Elf32_Word) ctx.virtual, - false, &symoffset)) != 0)) { - cursym = symname; - } else { - symoffset += 4; - } - } - - if (cursym != 0) { - sprintf (&ctx.data[ctx.datalen], "<%s+", cursym); - ctx.datalen = strlen (ctx.data); - sprintf (&ctx.data[ctx.datalen], ctx.radix_fmt, symoffset); - strcat (ctx.data, ">"); - ctx.datalen = strlen (ctx.data); - } - } -#endif /* USE_SOURCE_CODE */ - - ctx.instr = INSTRUCTION (memaddr); - - if (ctx.flags & F_INSTR) { - /* Find the opcode structure for this opcode. If one is not found - then it must be an illegal instruction */ - sprintf (&ctx.data[ctx.datalen], - " %02lx %02lx %02lx %02lx ", - ((ctx.instr >> 24) & 0xff), - ((ctx.instr >> 16) & 0xff), ((ctx.instr >> 8) & 0xff), - (ctx.instr & 0xff)); - ctx.datalen += 18; - } else { - strcat (ctx.data, " "); - ctx.datalen += 3; - } - - if ((ctx.op = find_opcode (ctx.instr)) == 0) { - /* Illegal Opcode */ - sprintf (&ctx.data[ctx.datalen], " .long 0x%08lx", - ctx.instr); - ctx.datalen += 24; - (*pfunc) (ctx.data); - continue; - } - - if (((ctx.flags & F_SIMPLE) == 0) || - (ctx.op->hfunc == 0) || - ((*ctx.op->hfunc) (&ctx) == false)) { - sprintf (&ctx.data[ctx.datalen], "%-7s ", ctx.op->name); - ctx.datalen += 8; - print_operands (&ctx); - } - - (*pfunc) (ctx.data); - } - - return true; -} /* disppc */ - - - -/*====================================================================== - * Called by the disassembler to print the operands for an instruction. - * - * Arguments: - * ctx A pointer to the disassembler context record. - * - * always returns 0. - */ - -int print_operands (struct ppc_ctx *ctx) -{ - int open_parens = 0; - int field; - unsigned long operand; - struct operand *opr; - -#ifdef USE_SOURCE_CODE - char *symname; - int offset; -#endif /* USE_SOURCE_CODE */ - /*------------------------------------------------------------*/ - - /* Walk through the operands and list each in order */ - for (field = 0; ctx->op->fields[field] != 0; ++field) { - if (ctx->op->fields[field] > n_operands) { - continue; /* bad operand ?! */ - } - - opr = &operands[ctx->op->fields[field] - 1]; - - if (opr->hint & OH_SILENT) { - continue; - } - - if ((field > 0) && !open_parens) { - strcat (ctx->data, ","); - ctx->datalen++; - } - - operand = (ctx->instr >> opr->shift) & ((1 << opr->bits) - 1); - - if (opr->hint & OH_ADDR) { - if ((operand & (1 << (opr->bits - 1))) != 0) { - operand = operand - (1 << opr->bits); - } - - if (ctx->op->hint & H_RELATIVE) - operand = (operand << 2) + (unsigned long) ctx->virtual; - else - operand = (operand << 2); - - - sprintf (&ctx->data[ctx->datalen], "0x%lx", operand); - ctx->datalen = strlen (ctx->data); - -#ifdef USE_SOURCE_CODE - if ((ctx->flags & F_SYMBOL) && - ((symname = - symbol_name_from_addr (operand, 0, &offset)) != 0)) { - sprintf (&ctx->data[ctx->datalen], " <%s", symname); - if (offset != 0) { - strcat (ctx->data, "+"); - ctx->datalen = strlen (ctx->data); - sprintf (&ctx->data[ctx->datalen], ctx->radix_fmt, - offset); - } - strcat (ctx->data, ">"); - } -#endif /* USE_SOURCE_CODE */ - } - - else if (opr->hint & OH_REG) { - if ((operand == 0) && - (opr->field == O_rA) && (ctx->op->hint & H_RA0_IS_0)) { - strcat (ctx->data, "0"); - } else { - sprintf (&ctx->data[ctx->datalen], "r%d", (short) operand); - } - - if (open_parens) { - strcat (ctx->data, ")"); - open_parens--; - } - } - - else if (opr->hint & OH_SPR) { - strcat (ctx->data, spr_name (operand)); - } - - else if (opr->hint & OH_TBR) { - strcat (ctx->data, tbr_name (operand)); - } - - else if (opr->hint & OH_LITERAL) { - switch (opr->field) { - case O_cr2: - strcat (ctx->data, "cr2"); - ctx->datalen += 3; - break; - - default: - break; - } - } - - else { - sprintf (&ctx->data[ctx->datalen], ctx->radix_fmt, - (unsigned short) operand); - - if (open_parens) { - strcat (ctx->data, ")"); - open_parens--; - } - - else if (opr->hint & OH_OFFSET) { - strcat (ctx->data, "("); - open_parens++; - } - } - - ctx->datalen = strlen (ctx->data); - } - - return 0; -} /* print_operands */ - - - -/*====================================================================== - * Called to get the value of an arbitrary operand with in an instruction. - * - * Arguments: - * op The pointer to the opcode structure to which - * the operands belong. - * - * instr The instruction (32 bits) containing the opcode - * and the operands to print. By the time that - * this routine is called the operand has already - * been added to the output. - * - * field The field (operand) to get the value of. - * - * value The address of an unsigned long to be filled in - * with the value of the operand if it is found. This - * will only be filled in if the function returns - * true. This may be passed as 0 if the value is - * not required. - * - * Returns true if the operand was found or false if it was not. - */ - -int get_operand_value (struct opcode *op, unsigned long instr, - enum OP_FIELD field, unsigned long *value) -{ - int i; - struct operand *opr; - - /*------------------------------------------------------------*/ - - if (field > n_operands) { - return false; /* bad operand ?! */ - } - - /* Walk through the operands and list each in order */ - for (i = 0; op->fields[i] != 0; ++i) { - if (op->fields[i] != field) { - continue; - } - - opr = &operands[op->fields[i] - 1]; - - if (value) { - *value = (instr >> opr->shift) & ((1 << opr->bits) - 1); - } - return true; - } - - return false; -} /* operand_value */ - - - -/*====================================================================== - * Called by the disassembler to match an opcode value to an opcode structure. - * - * Arguments: - * instr The instruction (32 bits) to match. This value - * may contain operand values as well as the opcode - * since they will be masked out anyway for this - * search. - * - * Returns the address of an opcode struct (from the opcode table) if the - * operand successfully matched an entry, or 0 if no match was found. - */ - -struct opcode *find_opcode (unsigned long instr) -{ - struct opcode *ptr; - int top = 0; - int bottom = n_opcodes - 1; - int idx; - - /*------------------------------------------------------------*/ - - while (top <= bottom) { - idx = (top + bottom) >> 1; - ptr = &opcodes[idx]; - - if ((instr & ptr->mask) < ptr->opcode) { - bottom = idx - 1; - } else if ((instr & ptr->mask) > ptr->opcode) { - top = idx + 1; - } else { - return ptr; - } - } - - return (struct opcode *) 0; -} /* find_opcode */ - - - -/*====================================================================== - * Called by the assembler to match an opcode name to an opcode structure. - * - * Arguments: - * name The text name of the opcode, e.g. "b", "mtspr", etc. - * - * The opcodes are sorted numerically by their instruction binary code - * so a search for the name cannot use the binary search used by the - * other find routine. - * - * Returns the address of an opcode struct (from the opcode table) if the - * name successfully matched an entry, or 0 if no match was found. - */ - -struct opcode *find_opcode_by_name (char *name) -{ - int idx; - - /*------------------------------------------------------------*/ - - downstring (name); - - for (idx = 0; idx < n_opcodes; ++idx) { - if (!strcmp (name, opcodes[idx].name)) - return &opcodes[idx]; - } - - return (struct opcode *) 0; -} /* find_opcode_by_name */ - - - -/*====================================================================== - * Convert the 'spr' operand from its numeric value to its symbolic name. - * - * Arguments: - * value The value of the 'spr' operand. This value should - * be unmodified from its encoding in the instruction. - * the split-field computations will be performed - * here before the switch. - * - * Returns the address of a character array containing the name of the - * special purpose register defined by the 'value' parameter, or the - * address of a character array containing "???" if no match was found. - */ - -char *spr_name (int value) -{ - unsigned short spr; - static char other[10]; - int i; - - /*------------------------------------------------------------*/ - - /* spr is a 10 bit field whose interpretation has the high and low - five-bit fields reversed from their encoding in the operand */ - - spr = ((value >> 5) & 0x1f) | ((value & 0x1f) << 5); - - for (i = 0; i < n_sprs; ++i) { - if (spr == spr_map[i].spr_val) - return spr_map[i].spr_name; - } - - sprintf (other, "%d", spr); - return other; -} /* spr_name */ - - - -/*====================================================================== - * Convert the 'spr' operand from its symbolic name to its numeric value - * - * Arguments: - * name The symbolic name of the 'spr' operand. The - * split-field encoding will be done by this routine. - * NOTE: name can be a number. - * - * Returns the numeric value for the spr appropriate for encoding a machine - * instruction. Returns 0 if unable to find the SPR. - */ - -int spr_value (char *name) -{ - struct spr_info *sprp; - int spr; - int i; - - /*------------------------------------------------------------*/ - - if (!name || !*name) - return 0; - - if (isdigit ((int) name[0])) { - i = htonl (read_number (name)); - spr = ((i >> 5) & 0x1f) | ((i & 0x1f) << 5); - return spr; - } - - downstring (name); - - for (i = 0; i < n_sprs; ++i) { - sprp = &spr_map[i]; - - if (strcmp (name, sprp->spr_name) == 0) { - /* spr is a 10 bit field whose interpretation has the high and low - five-bit fields reversed from their encoding in the operand */ - i = htonl (sprp->spr_val); - spr = ((i >> 5) & 0x1f) | ((i & 0x1f) << 5); - - return spr; - } - } - - return 0; -} /* spr_value */ - - - -/*====================================================================== - * Convert the 'tbr' operand from its numeric value to its symbolic name. - * - * Arguments: - * value The value of the 'tbr' operand. This value should - * be unmodified from its encoding in the instruction. - * the split-field computations will be performed - * here before the switch. - * - * Returns the address of a character array containing the name of the - * time base register defined by the 'value' parameter, or the address - * of a character array containing "???" if no match was found. - */ - -char *tbr_name (int value) -{ - unsigned short tbr; - - /*------------------------------------------------------------*/ - - /* tbr is a 10 bit field whose interpretation has the high and low - five-bit fields reversed from their encoding in the operand */ - - tbr = ((value >> 5) & 0x1f) | ((value & 0x1f) << 5); - - if (tbr == 268) - return "TBL"; - - else if (tbr == 269) - return "TBU"; - - - return "???"; -} /* tbr_name */ - - - -/*====================================================================== - * Convert the 'tbr' operand from its symbolic name to its numeric value. - * - * Arguments: - * name The symbolic name of the 'tbr' operand. The - * split-field encoding will be done by this routine. - * - * Returns the numeric value for the spr appropriate for encoding a machine - * instruction. Returns 0 if unable to find the TBR. - */ - -int tbr_value (char *name) -{ - int tbr; - int val; - - /*------------------------------------------------------------*/ - - if (!name || !*name) - return 0; - - downstring (name); - - if (isdigit ((int) name[0])) { - val = read_number (name); - - if (val != 268 && val != 269) - return 0; - } else if (strcmp (name, "tbl") == 0) - val = 268; - else if (strcmp (name, "tbu") == 0) - val = 269; - else - return 0; - - /* tbr is a 10 bit field whose interpretation has the high and low - five-bit fields reversed from their encoding in the operand */ - - val = htonl (val); - tbr = ((val >> 5) & 0x1f) | ((val & 0x1f) << 5); - return tbr; -} /* tbr_name */ - - - -/*====================================================================== - * The next several functions (handle_xxx) are the routines that handle - * disassembling the opcodes with simplified mnemonics. - * - * Arguments: - * ctx A pointer to the disassembler context record. - * - * Returns true if the simpler form was printed or false if it was not. - */ - -int handle_bc (struct ppc_ctx *ctx) -{ - unsigned long bo; - unsigned long bi; - static struct opcode blt = { B_OPCODE (16, 0, 0), B_MASK, {O_BD, 0}, - 0, "blt", H_RELATIVE - }; - static struct opcode bne = - { B_OPCODE (16, 0, 0), B_MASK, {O_cr2, O_BD, 0}, - 0, "bne", H_RELATIVE - }; - static struct opcode bdnz = { B_OPCODE (16, 0, 0), B_MASK, {O_BD, 0}, - 0, "bdnz", H_RELATIVE - }; - - /*------------------------------------------------------------*/ - - if (get_operand_value(ctx->op, ctx->instr, O_BO, &bo) == false) - return false; - - if (get_operand_value(ctx->op, ctx->instr, O_BI, &bi) == false) - return false; - - if ((bo == 12) && (bi == 0)) { - ctx->op = &blt; - sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name); - ctx->datalen += 8; - print_operands (ctx); - return true; - } else if ((bo == 4) && (bi == 10)) { - ctx->op = =⃥ - sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name); - ctx->datalen += 8; - print_operands (ctx); - return true; - } else if ((bo == 16) && (bi == 0)) { - ctx->op = &bdnz; - sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name); - ctx->datalen += 8; - print_operands (ctx); - return true; - } - - return false; -} /* handle_blt */ - - - -/*====================================================================== - * Outputs source line information for the disassembler. This should - * be modified in the future to lookup the actual line of source code - * from the file, but for now this will do. - * - * Arguments: - * filename The address of a character array containing the - * absolute path and file name of the source file. - * - * funcname The address of a character array containing the - * name of the function (not C++ demangled (yet)) - * to which this code belongs. - * - * line_no An integer specifying the source line number that - * generated this code. - * - * pfunc The address of a function to call to print the output. - * - * - * Returns true if it was able to output the line info, or false if it was - * not. - */ - -int print_source_line (char *filename, char *funcname, - int line_no, int (*pfunc) (const char *)) -{ - char out_buf[256]; - - /*------------------------------------------------------------*/ - - (*pfunc) (""); /* output a newline */ - sprintf (out_buf, "%s %s(): line %d", filename, funcname, line_no); - (*pfunc) (out_buf); - - return true; -} /* print_source_line */ - - - -/*====================================================================== - * Entry point for the PPC assembler. - * - * Arguments: - * asm_buf An array of characters containing the assembly opcode - * and operands to convert to a POWERPC machine - * instruction. - * - * Returns the machine instruction or zero. - */ - -unsigned long asmppc (unsigned long memaddr, char *asm_buf, int *err) -{ - struct opcode *opc; - struct operand *oper[MAX_OPERANDS]; - unsigned long instr; - unsigned long param; - char *ptr = asm_buf; - char scratch[20]; - int i; - int w_operands = 0; /* wanted # of operands */ - int n_operands = 0; /* # of operands read */ - int asm_debug = 0; - - /*------------------------------------------------------------*/ - - if (err) - *err = 0; - - if (get_word (&ptr, scratch) == 0) - return 0; - - /* Lookup the opcode structure based on the opcode name */ - if ((opc = find_opcode_by_name (scratch)) == (struct opcode *) 0) { - if (err) - *err = E_ASM_BAD_OPCODE; - return 0; - } - - if (asm_debug) { - printf ("asmppc: Opcode = \"%s\"\n", opc->name); - } - - for (i = 0; i < 8; ++i) { - if (opc->fields[i] == 0) - break; - ++w_operands; - } - - if (asm_debug) { - printf ("asmppc: Expecting %d operands\n", w_operands); - } - - instr = opc->opcode; - - /* read each operand */ - while (n_operands < w_operands) { - - oper[n_operands] = &operands[opc->fields[n_operands] - 1]; - - if (oper[n_operands]->hint & OH_SILENT) { - /* Skip silent operands, they are covered in opc->opcode */ - - if (asm_debug) { - printf ("asmppc: Operand %d \"%s\" SILENT\n", n_operands, - oper[n_operands]->name); - } - - ++n_operands; - continue; - } - - if (get_word (&ptr, scratch) == 0) - break; - - if (asm_debug) { - printf ("asmppc: Operand %d \"%s\" : \"%s\"\n", n_operands, - oper[n_operands]->name, scratch); - } - - if ((param = parse_operand (memaddr, opc, oper[n_operands], - scratch, err)) == -1) - return 0; - - instr |= param; - ++n_operands; - } - - if (n_operands < w_operands) { - if (err) - *err = E_ASM_NUM_OPERANDS; - return 0; - } - - if (asm_debug) { - printf ("asmppc: Instruction = 0x%08lx\n", instr); - } - - return instr; -} /* asmppc */ - - - -/*====================================================================== - * Called by the assembler to interpret a single operand - * - * Arguments: - * ctx A pointer to the disassembler context record. - * - * Returns 0 if the operand is ok, or -1 if it is bad. - */ - -int parse_operand (unsigned long memaddr, struct opcode *opc, - struct operand *oper, char *txt, int *err) -{ - long data; - long mask; - int is_neg = 0; - - /*------------------------------------------------------------*/ - - mask = (1 << oper->bits) - 1; - - if (oper->hint & OH_ADDR) { - data = read_number (txt); - - if (opc->hint & H_RELATIVE) - data = data - memaddr; - - if (data < 0) - is_neg = 1; - - data >>= 2; - data &= (mask >> 1); - - if (is_neg) - data |= 1 << (oper->bits - 1); - } - - else if (oper->hint & OH_REG) { - if (txt[0] == 'r' || txt[0] == 'R') - txt++; - else if (txt[0] == '%' && (txt[1] == 'r' || txt[1] == 'R')) - txt += 2; - - data = read_number (txt); - if (data > 31) { - if (err) - *err = E_ASM_BAD_REGISTER; - return -1; - } - - data = htonl (data); - } - - else if (oper->hint & OH_SPR) { - if ((data = spr_value (txt)) == 0) { - if (err) - *err = E_ASM_BAD_SPR; - return -1; - } - } - - else if (oper->hint & OH_TBR) { - if ((data = tbr_value (txt)) == 0) { - if (err) - *err = E_ASM_BAD_TBR; - return -1; - } - } - - else { - data = htonl (read_number (txt)); - } - - return (data & mask) << oper->shift; -} /* parse_operand */ - - -char *asm_error_str (int err) -{ - switch (err) { - case E_ASM_BAD_OPCODE: - return "Bad opcode"; - case E_ASM_NUM_OPERANDS: - return "Bad number of operands"; - case E_ASM_BAD_REGISTER: - return "Bad register number"; - case E_ASM_BAD_SPR: - return "Bad SPR name or number"; - case E_ASM_BAD_TBR: - return "Bad TBR name or number"; - } - - return ""; -} /* asm_error_str */ - - - -/*====================================================================== - * Copy a word from one buffer to another, ignores leading white spaces. - * - * Arguments: - * src The address of a character pointer to the - * source buffer. - * dest A pointer to a character buffer to write the word - * into. - * - * Returns the number of non-white space characters copied, or zero. - */ - -int get_word (char **src, char *dest) -{ - char *ptr = *src; - int nchars = 0; - - /*------------------------------------------------------------*/ - - /* Eat white spaces */ - while (*ptr && isblank (*ptr)) - ptr++; - - if (*ptr == 0) { - *src = ptr; - return 0; - } - - /* Find the text of the word */ - while (*ptr && !isblank (*ptr) && (*ptr != ',')) - dest[nchars++] = *ptr++; - ptr = (*ptr == ',') ? ptr + 1 : ptr; - dest[nchars] = 0; - - *src = ptr; - return nchars; -} /* get_word */ - - - -/*====================================================================== - * Convert a numeric string to a number, be aware of base notations. - * - * Arguments: - * txt The numeric string. - * - * Returns the converted numeric value. - */ - -long read_number (char *txt) -{ - long val; - int is_neg = 0; - - /*------------------------------------------------------------*/ - - if (txt == 0 || *txt == 0) - return 0; - - if (*txt == '-') { - is_neg = 1; - ++txt; - } - - if (txt[0] == '0' && (txt[1] == 'x' || txt[1] == 'X')) /* hex */ - val = hextoul(&txt[2], NULL); - else /* decimal */ - val = dectoul(txt, NULL); - - if (is_neg) - val = -val; - - return val; -} /* read_number */ - - -int downstring (char *s) -{ - if (!s || !*s) - return 0; - - while (*s) { - if (isupper (*s)) - *s = tolower (*s); - s++; - } - - return 0; -} /* downstring */ - - - -/*====================================================================== - * Examines the instruction at the current address and determines the - * next address to be executed. This will take into account branches - * of different types so that a "step" and "next" operations can be - * supported. - * - * Arguments: - * nextaddr The address (to be filled in) of the next - * instruction to execute. This will only be a valid - * address if true is returned. - * - * step_over A flag indicating how to compute addresses for - * branch statements: - * true = Step over the branch (next) - * false = step into the branch (step) - * - * Returns true if it was able to compute the address. Returns false if - * it has a problem reading the current instruction or one of the registers. - */ - -int find_next_address (unsigned char *nextaddr, int step_over, - struct pt_regs *regs) -{ - unsigned long pc; /* SRR0 register from PPC */ - unsigned long ctr; /* CTR register from PPC */ - unsigned long cr; /* CR register from PPC */ - unsigned long lr; /* LR register from PPC */ - unsigned long instr; /* instruction at SRR0 */ - unsigned long next; /* computed instruction for 'next' */ - unsigned long step; /* computed instruction for 'step' */ - unsigned long addr = 0; /* target address operand */ - unsigned long aa = 0; /* AA operand */ - unsigned long lk = 0; /* LK operand */ - unsigned long bo = 0; /* BO operand */ - unsigned long bi = 0; /* BI operand */ - struct opcode *op = 0; /* opcode structure for 'instr' */ - int ctr_ok = 0; - int cond_ok = 0; - int conditional = 0; - int branch = 0; - - /*------------------------------------------------------------*/ - - if (nextaddr == 0 || regs == 0) { - printf ("find_next_address: bad args"); - return false; - } - - pc = regs->nip & 0xfffffffc; - instr = INSTRUCTION (pc); - - if ((op = find_opcode (instr)) == (struct opcode *) 0) { - printf ("find_next_address: can't parse opcode 0x%lx", instr); - return false; - } - - ctr = regs->ctr; - cr = regs->ccr; - lr = regs->link; - - switch (op->opcode) { - case B_OPCODE (16, 0, 0): /* bc */ - case B_OPCODE (16, 0, 1): /* bcl */ - case B_OPCODE (16, 1, 0): /* bca */ - case B_OPCODE (16, 1, 1): /* bcla */ - if (!get_operand_value (op, instr, O_BD, &addr) || - !get_operand_value (op, instr, O_BO, &bo) || - !get_operand_value (op, instr, O_BI, &bi) || - !get_operand_value (op, instr, O_AA, &aa) || - !get_operand_value (op, instr, O_LK, &lk)) - return false; - - if ((addr & (1 << 13)) != 0) - addr = addr - (1 << 14); - addr <<= 2; - conditional = 1; - branch = 1; - break; - - case I_OPCODE (18, 0, 0): /* b */ - case I_OPCODE (18, 0, 1): /* bl */ - case I_OPCODE (18, 1, 0): /* ba */ - case I_OPCODE (18, 1, 1): /* bla */ - if (!get_operand_value (op, instr, O_LI, &addr) || - !get_operand_value (op, instr, O_AA, &aa) || - !get_operand_value (op, instr, O_LK, &lk)) - return false; - - if ((addr & (1 << 23)) != 0) - addr = addr - (1 << 24); - addr <<= 2; - conditional = 0; - branch = 1; - break; - - case XL_OPCODE (19, 528, 0): /* bcctr */ - case XL_OPCODE (19, 528, 1): /* bcctrl */ - if (!get_operand_value (op, instr, O_BO, &bo) || - !get_operand_value (op, instr, O_BI, &bi) || - !get_operand_value (op, instr, O_LK, &lk)) - return false; - - addr = ctr; - aa = 1; - conditional = 1; - branch = 1; - break; - - case XL_OPCODE (19, 16, 0): /* bclr */ - case XL_OPCODE (19, 16, 1): /* bclrl */ - if (!get_operand_value (op, instr, O_BO, &bo) || - !get_operand_value (op, instr, O_BI, &bi) || - !get_operand_value (op, instr, O_LK, &lk)) - return false; - - addr = lr; - aa = 1; - conditional = 1; - branch = 1; - break; - - default: - conditional = 0; - branch = 0; - break; - } - - if (conditional) { - switch ((bo & 0x1e) >> 1) { - case 0: /* 0000y */ - if (--ctr != 0) - ctr_ok = 1; - - cond_ok = !(cr & (1 << (31 - bi))); - break; - - case 1: /* 0001y */ - if (--ctr == 0) - ctr_ok = 1; - - cond_ok = !(cr & (1 << (31 - bi))); - break; - - case 2: /* 001zy */ - ctr_ok = 1; - cond_ok = !(cr & (1 << (31 - bi))); - break; - - case 4: /* 0100y */ - if (--ctr != 0) - ctr_ok = 1; - - cond_ok = cr & (1 << (31 - bi)); - break; - - case 5: /* 0101y */ - if (--ctr == 0) - ctr_ok = 1; - - cond_ok = cr & (1 << (31 - bi)); - break; - - case 6: /* 011zy */ - ctr_ok = 1; - cond_ok = cr & (1 << (31 - bi)); - break; - - case 8: /* 1z00y */ - if (--ctr != 0) - ctr_ok = cond_ok = 1; - break; - - case 9: /* 1z01y */ - if (--ctr == 0) - ctr_ok = cond_ok = 1; - break; - - case 10: /* 1z1zz */ - ctr_ok = cond_ok = 1; - break; - } - } - - if (branch && (!conditional || (ctr_ok && cond_ok))) { - if (aa) - step = addr; - else - step = addr + pc; - - if (lk) - next = pc + 4; - else - next = step; - } else { - step = next = pc + 4; - } - - if (step_over == true) - *(unsigned long *) nextaddr = next; - else - *(unsigned long *) nextaddr = step; - - return true; -} /* find_next_address */ - - -/* - * Copyright (c) 2000 William L. Pitts and W. Gerald Hicks - * All rights reserved. - * - * Redistribution and use in source and binary forms are freely - * permitted provided that the above copyright notice and this - * paragraph and the following disclaimer are duplicated in all - * such forms. - * - * This software is provided "AS IS" and without any express or - * implied warranties, including, without limitation, the implied - * warranties of merchantability and fitness for a particular - * purpose. - */ diff --git a/common/board_r.c b/common/board_r.c index 760c2d05ed..f81d21a282 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -23,10 +23,6 @@ #include #include #include -/* TODO: can we just include all these headers whether needed or not? */ -#if defined(CONFIG_CMD_BEDBUG) -#include -#endif #include #include #include @@ -37,6 +33,7 @@ #include #include #include +/* TODO: can we just include all these headers whether needed or not? */ #if defined(CONFIG_CMD_KGDB) #include #endif @@ -820,10 +817,6 @@ static init_fnc_t init_sequence_r[] = { */ last_stage_init, #endif -#ifdef CONFIG_CMD_BEDBUG - INIT_FUNC_WATCHDOG_RESET - bedbug_init, -#endif #if defined(CONFIG_PRAM) initr_mem, #endif -- cgit v1.2.3