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

📄 armcopro.c

📁 这个是LINUX下的GDB调度工具的源码
💻 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"#include "ansidecl.h"#include "iwmmxt.h"/* 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.  */  XScale_cp15_opcode_2_is_0_Regs[0] = 0x69052000;  /* 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.  */  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;}/* 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);  return TRUE;}/* Check for special XScale memory access features.  */voidXScale_check_memacc (ARMul_State * state, ARMword * address, int store){  ARMword dbcon, r0, r1;  int e1, e0;  if (!state->is_XScale)    return;  /* Check for PID-ification.     XXX BTB access support will require this test failing.  */  r0 = (read_cp15_reg (13, 0, 0) & 0xfe000000);  if (r0 && (* address & 0xfe000000) == 0)    * address |= r0;  /* Check alignment fault enable/disable.  */  if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN) && (* address & 3))    {      /* Set the FSR and FAR.

⌨️ 快捷键说明

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