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

📄 armcopro.c

📁 skyeye的开源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  armcopro.c -- co-processor interface:  ARM6 Instruction Emulator.    Copyright (C) 1994, 2000 Advanced RISC Machines Ltd.     This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.     This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.     You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */#include "armdefs.h"#include "armos.h"#include "armemu.h"//chy 2005-07-08#include "ansidecl.h"//chy -------//#include "iwmmxt.h"//chy 2005-09-19 add CP6 MRC support (for get irq number and base)extern unsigned xscale_cp6_mrc (ARMul_State * state, unsigned type,				ARMword instr, ARMword * data);//chy 2005-09-19---------------extern unsigned xscale_cp13_init (ARMul_State * state);extern unsigned xscale_cp13_exit (ARMul_State * state);extern unsigned xscale_cp13_ldc (ARMul_State * state, unsigned type,				 ARMword instr, ARMword data);extern unsigned xscale_cp13_stc (ARMul_State * state, unsigned type,				 ARMword instr, ARMword * data);extern unsigned xscale_cp13_mrc (ARMul_State * state, unsigned type,				 ARMword instr, ARMword * data);extern unsigned xscale_cp13_mcr (ARMul_State * state, unsigned type,				 ARMword instr, ARMword data);extern unsigned xscale_cp13_cdp (ARMul_State * state, unsigned type,				 ARMword instr);extern unsigned xscale_cp13_read_reg (ARMul_State * state, unsigned reg,				      ARMword * data);extern unsigned xscale_cp13_write_reg (ARMul_State * state, unsigned reg,				       ARMword data);extern unsigned xscale_cp14_init (ARMul_State * state);extern unsigned xscale_cp14_exit (ARMul_State * state);extern unsigned xscale_cp14_ldc (ARMul_State * state, unsigned type,				 ARMword instr, ARMword data);extern unsigned xscale_cp14_stc (ARMul_State * state, unsigned type,				 ARMword instr, ARMword * data);extern unsigned xscale_cp14_mrc (ARMul_State * state, unsigned type,				 ARMword instr, ARMword * data);extern unsigned xscale_cp14_mcr (ARMul_State * state, unsigned type,				 ARMword instr, ARMword data);extern unsigned xscale_cp14_cdp (ARMul_State * state, unsigned type,				 ARMword instr);extern unsigned xscale_cp14_read_reg (ARMul_State * state, unsigned reg,				      ARMword * data);extern unsigned xscale_cp14_write_reg (ARMul_State * state, unsigned reg,				       ARMword data);extern unsigned xscale_cp15_init (ARMul_State * state);extern unsigned xscale_cp15_exit (ARMul_State * state);extern unsigned xscale_cp15_ldc (ARMul_State * state, unsigned type,				 ARMword instr, ARMword data);extern unsigned xscale_cp15_stc (ARMul_State * state, unsigned type,				 ARMword instr, ARMword * data);extern unsigned xscale_cp15_mrc (ARMul_State * state, unsigned type,				 ARMword instr, ARMword * data);extern unsigned xscale_cp15_mcr (ARMul_State * state, unsigned type,				 ARMword instr, ARMword data);extern unsigned xscale_cp15_cdp (ARMul_State * state, unsigned type,				 ARMword instr);extern unsigned xscale_cp15_read_reg (ARMul_State * state, unsigned reg,				      ARMword * data);extern unsigned xscale_cp15_write_reg (ARMul_State * state, unsigned reg,				       ARMword data);/* Dummy Co-processors.  */static unsignedNoCoPro3R (ARMul_State * state ATTRIBUTE_UNUSED,	   unsigned a ATTRIBUTE_UNUSED, ARMword b ATTRIBUTE_UNUSED){	return ARMul_CANT;}static unsignedNoCoPro4R (ARMul_State * state ATTRIBUTE_UNUSED,	   unsigned a ATTRIBUTE_UNUSED,	   ARMword b ATTRIBUTE_UNUSED, ARMword c ATTRIBUTE_UNUSED){	return ARMul_CANT;}static unsignedNoCoPro4W (ARMul_State * state ATTRIBUTE_UNUSED,	   unsigned a ATTRIBUTE_UNUSED,	   ARMword b ATTRIBUTE_UNUSED, ARMword * c ATTRIBUTE_UNUSED){	return ARMul_CANT;}/* The XScale Co-processors.  *//* Coprocessor 15:  System Control.  */static void write_cp14_reg (unsigned, ARMword);static ARMword read_cp14_reg (unsigned);/* There are two sets of registers for copro 15.   One set is available when opcode_2 is 0 and   the other set when opcode_2 >= 1.  */static ARMword XScale_cp15_opcode_2_is_0_Regs[16];static ARMword XScale_cp15_opcode_2_is_not_0_Regs[16];/* There are also a set of breakpoint registers   which are accessed via CRm instead of opcode_2.  */static ARMword XScale_cp15_DBR1;static ARMword XScale_cp15_DBCON;static ARMword XScale_cp15_IBCR0;static ARMword XScale_cp15_IBCR1;static unsignedXScale_cp15_init (ARMul_State * state ATTRIBUTE_UNUSED){	int i;	for (i = 16; i--;) {		XScale_cp15_opcode_2_is_0_Regs[i] = 0;		XScale_cp15_opcode_2_is_not_0_Regs[i] = 0;	}	/* Initialise the processor ID.  */	//chy 2003-03-24, is same as cpu id in skyeye_options.c	//XScale_cp15_opcode_2_is_0_Regs[0] = 0x69052000;	XScale_cp15_opcode_2_is_0_Regs[0] = 0x69050000;	/* Initialise the cache type.  */	XScale_cp15_opcode_2_is_not_0_Regs[0] = 0x0B1AA1AA;	/* Initialise the ARM Control Register.  */	XScale_cp15_opcode_2_is_0_Regs[1] = 0x00000078;}/* Check an access to a register.  */static unsignedcheck_cp15_access (ARMul_State * state,		   unsigned reg,		   unsigned CRm, unsigned opcode_1, unsigned opcode_2){	/* Do not allow access to these register in USER mode.  */	//chy 2006-02-16 , should not consider system mode, don't conside 26bit mode	if (state->Mode == USER26MODE || state->Mode == USER32MODE )		return ARMul_CANT;	/* Opcode_1should be zero.  */	if (opcode_1 != 0)		return ARMul_CANT;	/* Different register have different access requirements.  */	switch (reg) {	case 0:	case 1:		/* CRm must be 0.  Opcode_2 can be anything.  */		if (CRm != 0)			return ARMul_CANT;		break;	case 2:	case 3:		/* CRm must be 0.  Opcode_2 must be zero.  */		if ((CRm != 0) || (opcode_2 != 0))			return ARMul_CANT;		break;	case 4:		/* Access not allowed.  */		return ARMul_CANT;	case 5:	case 6:		/* Opcode_2 must be zero.  CRm must be 0.  */		if ((CRm != 0) || (opcode_2 != 0))			return ARMul_CANT;		break;	case 7:		/* Permissable combinations:		   Opcode_2  CRm		   0       5		   0       6		   0       7		   1       5		   1       6		   1      10		   4      10		   5       2		   6       5  */		switch (opcode_2) {		default:			return ARMul_CANT;		case 6:			if (CRm != 5)				return ARMul_CANT;			break;		case 5:			if (CRm != 2)				return ARMul_CANT;			break;		case 4:			if (CRm != 10)				return ARMul_CANT;			break;		case 1:			if ((CRm != 5) && (CRm != 6) && (CRm != 10))				return ARMul_CANT;			break;		case 0:			if ((CRm < 5) || (CRm > 7))				return ARMul_CANT;			break;		}		break;	case 8:		/* Permissable combinations:		   Opcode_2  CRm		   0       5		   0       6		   0       7		   1       5		   1       6  */		if (opcode_2 > 1)			return ARMul_CANT;		if ((CRm < 5) || (CRm > 7))			return ARMul_CANT;		if (opcode_2 == 1 && CRm == 7)			return ARMul_CANT;		break;	case 9:		/* Opcode_2 must be zero or one.  CRm must be 1 or 2.  */		if (((CRm != 0) && (CRm != 1))		    || ((opcode_2 != 1) && (opcode_2 != 2)))			return ARMul_CANT;		break;	case 10:		/* Opcode_2 must be zero or one.  CRm must be 4 or 8.  */		if (((CRm != 0) && (CRm != 1))		    || ((opcode_2 != 4) && (opcode_2 != 8)))			return ARMul_CANT;		break;	case 11:		/* Access not allowed.  */		return ARMul_CANT;	case 12:		/* Access not allowed.  */		return ARMul_CANT;	case 13:		/* Opcode_2 must be zero.  CRm must be 0.  */		if ((CRm != 0) || (opcode_2 != 0))			return ARMul_CANT;		break;	case 14:		/* Opcode_2 must be 0.  CRm must be 0, 3, 4, 8 or 9.  */		if (opcode_2 != 0)			return ARMul_CANT;		if ((CRm != 0) && (CRm != 3) && (CRm != 4) && (CRm != 8)		    && (CRm != 9))			return ARMul_CANT;		break;	case 15:		/* Opcode_2 must be zero.  CRm must be 1.  */		if ((CRm != 1) || (opcode_2 != 0))			return ARMul_CANT;		break;	default:		/* Should never happen.  */		return ARMul_CANT;	}	return ARMul_DONE;}//chy 2003-09-03 commit below funs#if 0/* Store a value into one of coprocessor 15's registers.  */static voidwrite_cp15_reg (ARMul_State * state,		unsigned reg, unsigned opcode_2, unsigned CRm, ARMword value){	if (opcode_2) {		switch (reg) {		case 0:	/* Cache Type.  */			/* Writes are not allowed.  */			return;		case 1:	/* Auxillary Control.  */			/* Only BITS (5, 4) and BITS (1, 0) can be written.  */			value &= 0x33;			break;		default:			return;		}		XScale_cp15_opcode_2_is_not_0_Regs[reg] = value;	}	else {		switch (reg) {		case 0:	/* ID.  */			/* Writes are not allowed.  */			return;		case 1:	/* ARM Control.  */			/* Only BITS (13, 11), BITS (9, 7) and BITS (2, 0) can be written.			   BITS (31, 14) and BIT (10) write as zero, BITS (6, 3) write as one.  */			value &= 0x00003b87;			value |= 0x00000078;			/* Change the endianness if necessary.  */			if ((value & ARMul_CP15_R1_ENDIAN) !=			    (XScale_cp15_opcode_2_is_0_Regs[reg] &			     ARMul_CP15_R1_ENDIAN)) {				state->bigendSig =					value & ARMul_CP15_R1_ENDIAN;				/* Force ARMulator to notice these now.  */				state->Emulate = CHANGEMODE;			}			break;		case 2:	/* Translation Table Base.  */			/* Only BITS (31, 14) can be written.  */			value &= 0xffffc000;			break;		case 3:	/* Domain Access Control.  */			/* All bits writable.  */			break;		case 5:	/* Fault Status Register.  */			/* BITS (10, 9) and BITS (7, 0) can be written.  */			value &= 0x000006ff;			break;		case 6:	/* Fault Address Register.  */			/* All bits writable.  */			break;		case 7:	/* Cache Functions.  */		case 8:	/* TLB Operations.  */		case 10:	/* TLB Lock Down.  */			/* Ignore writes.  */			return;		case 9:	/* Data Cache Lock.  */			/* Only BIT (0) can be written.  */			value &= 0x1;			break;		case 13:	/* Process ID.  */			/* Only BITS (31, 25) are writable.  */			value &= 0xfe000000;			break;		case 14:	/* DBR0, DBR1, DBCON, IBCR0, IBCR1 */			/* All bits can be written.  Which register is accessed is			   dependent upon CRm.  */			switch (CRm) {			case 0:	/* DBR0 */				break;			case 3:	/* DBR1 */				XScale_cp15_DBR1 = value;				break;			case 4:	/* DBCON */				XScale_cp15_DBCON = value;				break;			case 8:	/* IBCR0 */				XScale_cp15_IBCR0 = value;				break;			case 9:	/* IBCR1 */				XScale_cp15_IBCR1 = value;				break;			default:				return;			}			break;		case 15:	/* Coprpcessor Access Register.  */			/* Access is only valid if CRm == 1.  */			if (CRm != 1)				return;			/* Only BITS (13, 0) may be written.  */			value &= 0x00003fff;			break;		default:			return;		}		XScale_cp15_opcode_2_is_0_Regs[reg] = value;	}	return;}/* Return the value in a cp15 register.  */ARMwordread_cp15_reg (unsigned reg, unsigned opcode_2, unsigned CRm){	if (opcode_2 == 0) {		if (reg == 15 && CRm != 1)			return 0;		if (reg == 14) {			switch (CRm) {			case 3:				return XScale_cp15_DBR1;			case 4:				return XScale_cp15_DBCON;			case 8:				return XScale_cp15_IBCR0;			case 9:				return XScale_cp15_IBCR1;			default:				break;			}		}		return XScale_cp15_opcode_2_is_0_Regs[reg];	}	else		return XScale_cp15_opcode_2_is_not_0_Regs[reg];	return 0;}static unsignedXScale_cp15_LDC (ARMul_State * state, unsigned type, ARMword instr,		 ARMword data){	unsigned reg = BITS (12, 15);	unsigned result;	result = check_cp15_access (state, reg, 0, 0, 0);	if (result == ARMul_DONE && type == ARMul_DATA)		write_cp15_reg (state, reg, 0, 0, data);	return result;}static unsignedXScale_cp15_STC (ARMul_State * state, unsigned type, ARMword instr,		 ARMword * data){	unsigned reg = BITS (12, 15);	unsigned result;	result = check_cp15_access (state, reg, 0, 0, 0);	if (result == ARMul_DONE && type == ARMul_DATA)		*data = read_cp15_reg (reg, 0, 0);	return result;}static unsignedXScale_cp15_MRC (ARMul_State * state,		 unsigned type ATTRIBUTE_UNUSED,		 ARMword instr, ARMword * value){	unsigned opcode_2 = BITS (5, 7);	unsigned CRm = BITS (0, 3);	unsigned reg = BITS (16, 19);	unsigned result;	result = check_cp15_access (state, reg, CRm, BITS (21, 23), opcode_2);	if (result == ARMul_DONE)		*value = read_cp15_reg (reg, opcode_2, CRm);	return result;}static unsignedXScale_cp15_MCR (ARMul_State * state,		 unsigned type ATTRIBUTE_UNUSED, ARMword instr, ARMword value){	unsigned opcode_2 = BITS (5, 7);	unsigned CRm = BITS (0, 3);	unsigned reg = BITS (16, 19);	unsigned result;	result = check_cp15_access (state, reg, CRm, BITS (21, 23), opcode_2);	if (result == ARMul_DONE)		write_cp15_reg (state, reg, opcode_2, CRm, value);	return result;}static unsignedXScale_cp15_read_reg (ARMul_State * state ATTRIBUTE_UNUSED,		      unsigned reg, ARMword * value){	/* FIXME: Not sure what to do about the alternative register set	   here.  For now default to just accessing CRm == 0 registers.  */	*value = read_cp15_reg (reg, 0, 0);	return TRUE;}static unsignedXScale_cp15_write_reg (ARMul_State * state ATTRIBUTE_UNUSED,		       unsigned reg, ARMword value){	/* FIXME: Not sure what to do about the alternative register set	   here.  For now default to just accessing CRm == 0 registers.  */	write_cp15_reg (state, reg, 0, 0, value);

⌨️ 快捷键说明

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