⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bedbug.c.svn-base

📁 u-boot loader common files, like cpu, clock, environment...etc...
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
	} 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 = &bne;		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 = simple_strtoul (&txt[2], NULL, 16);	else						/* decimal */		val = simple_strtoul (txt, NULL, 10);	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. */#endif	/* CONFIG_COMMANDS & CFG_CMD_BEDBUG */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -