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

📄 armemu.c

📁 skyeye的开源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  armemu.c -- Main instruction emulation:  ARM7 Instruction Emulator.    Copyright (C) 1994 Advanced RISC Machines Ltd.    Modifications to add arch. v4 support by <jsmith@cygnus.com>.     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 "armemu.h"#include "armos.h"#include "skyeye2gdb.h"//#include "iwmmxt.h"//chy 2003-07-11: for debug instrs//extern int skyeye_instr_debug;extern FILE *skyeye_logfd;static ARMword GetDPRegRHS (ARMul_State *, ARMword);static ARMword GetDPSRegRHS (ARMul_State *, ARMword);static void WriteR15 (ARMul_State *, ARMword);static void WriteSR15 (ARMul_State *, ARMword);static void WriteR15Branch (ARMul_State *, ARMword);static ARMword GetLSRegRHS (ARMul_State *, ARMword);static ARMword GetLS7RHS (ARMul_State *, ARMword);static unsigned LoadWord (ARMul_State *, ARMword, ARMword);static unsigned LoadHalfWord (ARMul_State *, ARMword, ARMword, int);static unsigned LoadByte (ARMul_State *, ARMword, ARMword, int);static unsigned StoreWord (ARMul_State *, ARMword, ARMword);static unsigned StoreHalfWord (ARMul_State *, ARMword, ARMword);static unsigned StoreByte (ARMul_State *, ARMword, ARMword);static void LoadMult (ARMul_State *, ARMword, ARMword, ARMword);static void StoreMult (ARMul_State *, ARMword, ARMword, ARMword);static void LoadSMult (ARMul_State *, ARMword, ARMword, ARMword);static void StoreSMult (ARMul_State *, ARMword, ARMword, ARMword);static unsigned Multiply64 (ARMul_State *, ARMword, int, int);static unsigned MultiplyAdd64 (ARMul_State *, ARMword, int, int);static void Handle_Load_Double (ARMul_State *, ARMword);static void Handle_Store_Double (ARMul_State *, ARMword);static inthandle_v6_insn (ARMul_State * state, ARMword instr);#define LUNSIGNED (0)		/* unsigned operation */#define LSIGNED   (1)		/* signed operation */#define LDEFAULT  (0)		/* default : do nothing */#define LSCC      (1)		/* set condition codes on result */#ifdef NEED_UI_LOOP_HOOK/* How often to run the ui_loop update, when in use.  */#define UI_LOOP_POLL_INTERVAL 0x32000/* Counter for the ui_loop_hook update.  */static int ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;/* Actual hook to call to run through gdb's gui event loop.  */extern int (*ui_loop_hook) (int);#endif /* NEED_UI_LOOP_HOOK */extern int stop_simulator;/* Short-hand macros for LDR/STR.  *//* Store post decrement writeback.  */#define SHDOWNWB()                                      \  lhs = LHS ;                                           \  if (StoreHalfWord (state, instr, lhs))                \     LSBase = lhs - GetLS7RHS (state, instr);/* Store post increment writeback.  */#define SHUPWB()                                        \  lhs = LHS ;                                           \  if (StoreHalfWord (state, instr, lhs))                \     LSBase = lhs + GetLS7RHS (state, instr);/* Store pre decrement.  */#define SHPREDOWN()                                     \  (void)StoreHalfWord (state, instr, LHS - GetLS7RHS (state, instr));/* Store pre decrement writeback.  */#define SHPREDOWNWB()                                   \  temp = LHS - GetLS7RHS (state, instr);                \  if (StoreHalfWord (state, instr, temp))               \     LSBase = temp;/* Store pre increment.  */#define SHPREUP()                                       \  (void)StoreHalfWord (state, instr, LHS + GetLS7RHS (state, instr));/* Store pre increment writeback.  */#define SHPREUPWB()                                     \  temp = LHS + GetLS7RHS (state, instr);                \  if (StoreHalfWord (state, instr, temp))               \     LSBase = temp;/* Load post decrement writeback.  */#define LHPOSTDOWN()                                    \{                                                       \  int done = 1;                                        	\  lhs = LHS;						\  temp = lhs - GetLS7RHS (state, instr);		\  							\  switch (BITS (5, 6))					\    {                                  			\    case 1: /* H */                                     \      if (LoadHalfWord (state, instr, lhs, LUNSIGNED))  \         LSBase = temp;        				\      break;                                           	\    case 2: /* SB */                                    \      if (LoadByte (state, instr, lhs, LSIGNED))        \         LSBase = temp;        				\      break;                                           	\    case 3: /* SH */                                    \      if (LoadHalfWord (state, instr, lhs, LSIGNED))    \         LSBase = temp;        				\      break;                                           	\    case 0: /* SWP handled elsewhere.  */               \    default:                                            \      done = 0;                                        	\      break;                                           	\    }                                                   \  if (done)                                             \     break;                                            	\}/* Load post increment writeback.  */#define LHPOSTUP()                                      \{                                                       \  int done = 1;                                        	\  lhs = LHS;                                           	\  temp = lhs + GetLS7RHS (state, instr);		\  							\  switch (BITS (5, 6))					\    {                                  			\    case 1: /* H */                                     \      if (LoadHalfWord (state, instr, lhs, LUNSIGNED))  \         LSBase = temp;        				\      break;                                           	\    case 2: /* SB */                                    \      if (LoadByte (state, instr, lhs, LSIGNED))        \         LSBase = temp;        				\      break;                                           	\    case 3: /* SH */                                    \      if (LoadHalfWord (state, instr, lhs, LSIGNED))    \         LSBase = temp;        				\      break;                                           	\    case 0: /* SWP handled elsewhere.  */               \    default:                                            \      done = 0;                                        	\      break;                                           	\    }                                                   \  if (done)                                             \     break;                                            	\}/* Load pre decrement.  */#define LHPREDOWN()                                     	\{                                                       	\  int done = 1;                                        		\								\  temp = LHS - GetLS7RHS (state, instr);                 	\  switch (BITS (5, 6))						\    {                                  				\    case 1: /* H */                                     	\      (void) LoadHalfWord (state, instr, temp, LUNSIGNED);  	\      break;                                           		\    case 2: /* SB */                                    	\      (void) LoadByte (state, instr, temp, LSIGNED);        	\      break;                                           		\    case 3: /* SH */                                    	\      (void) LoadHalfWord (state, instr, temp, LSIGNED);    	\      break;                                           		\    case 0:							\      /* SWP handled elsewhere.  */                 		\    default:                                            	\      done = 0;                                        		\      break;                                           		\    }                                                   	\  if (done)                                             	\     break;                                            		\}/* Load pre decrement writeback.  */#define LHPREDOWNWB()                                   	\{                                                       	\  int done = 1;                                        		\								\  temp = LHS - GetLS7RHS (state, instr);                	\  switch (BITS (5, 6))						\    {                                  				\    case 1: /* H */                                     	\      if (LoadHalfWord (state, instr, temp, LUNSIGNED))     	\         LSBase = temp;                                		\      break;                                           		\    case 2: /* SB */                                    	\      if (LoadByte (state, instr, temp, LSIGNED))           	\         LSBase = temp;                                		\      break;                                           		\    case 3: /* SH */                                    	\      if (LoadHalfWord (state, instr, temp, LSIGNED))       	\         LSBase = temp;                                		\      break;                                           		\    case 0:							\      /* SWP handled elsewhere.  */                 		\    default:                                            	\      done = 0;                                        		\      break;                                           		\    }                                                   	\  if (done)                                             	\     break;                                            		\}/* Load pre increment.  */#define LHPREUP()                                       	\{                                                       	\  int done = 1;                                        		\								\  temp = LHS + GetLS7RHS (state, instr);                 	\  switch (BITS (5, 6))						\    {                                  				\    case 1: /* H */                                     	\      (void) LoadHalfWord (state, instr, temp, LUNSIGNED);  	\      break;                                           		\    case 2: /* SB */                                    	\      (void) LoadByte (state, instr, temp, LSIGNED);        	\      break;                                           		\    case 3: /* SH */                                    	\      (void) LoadHalfWord (state, instr, temp, LSIGNED);    	\      break;                                           		\    case 0:							\      /* SWP handled elsewhere.  */                 		\    default:                                            	\      done = 0;                                        		\      break;                                           		\    }                                                   	\  if (done)                                             	\     break;                                            		\}/* Load pre increment writeback.  */#define LHPREUPWB()                                     	\{                                                       	\  int done = 1;                                        		\								\  temp = LHS + GetLS7RHS (state, instr);                	\  switch (BITS (5, 6))						\    {                                  				\    case 1: /* H */                                     	\      if (LoadHalfWord (state, instr, temp, LUNSIGNED))     	\	LSBase = temp;                                		\      break;                                           		\    case 2: /* SB */                                    	\      if (LoadByte (state, instr, temp, LSIGNED))           	\	LSBase = temp;                                		\      break;                                           		\    case 3: /* SH */                                    	\      if (LoadHalfWord (state, instr, temp, LSIGNED))       	\	LSBase = temp;                                		\      break;                                           		\    case 0:							\      /* SWP handled elsewhere.  */                 		\    default:                                            	\      done = 0;                                        		\      break;                                           		\    }                                                   	\  if (done)                                             	\     break;                                            		\}/*ywc 2005-03-31*///teawater add for arm2x86 2005.02.17-------------------------------------------#include "dbct/tb.h"#ifndef NO_DBCT#include "dbct/arm2x86_self.h"#endif//AJ2D--------------------------------------------------------------------------/* EMULATION of ARM6.  *//* The PC pipeline value depends on whether ARM   or Thumb instructions are being executed.  */ARMword isize;extern int debugmode;#ifdef MODE32//chy 2006-04-12, for ICE debugint ARMul_ICE_debug(ARMul_State *state,ARMword instr,ARMword addr){ int i; if(debugmode){   if (instr == ARMul_ABORTWORD) return 0;   for (i=0;i<skyeye_ice.num_bps;i++){	 if(skyeye_ice.bps[i] == addr){		 //for test		 //printf("SKYEYE: ICE_debug bps [%d]== 0x%x\n", i,addr);		 state->EndCondition = 0;		 state->Emulate = STOP;		 return 1;	 }    }    if (skyeye_ice.tps_status==TRACE_STARTED)    {        for (i=0;i<skyeye_ice.num_tps;i++)        {            if (((skyeye_ice.tps[i].tp_address==addr)&&(skyeye_ice.tps[i].status==TRACEPOINT_ENABLED))||(skyeye_ice.tps[i].status==TRACEPOINT_STEPPING))            {                handle_tracepoint(i);            }     }    } } return 0;}/*void chy_debug(){	printf("SkyEye chy_deubeg begin\n");}*/ARMwordARMul_Emulate32 (ARMul_State * state)#elseARMwordARMul_Emulate26 (ARMul_State * state)#endif{	ARMword instr;		/* The current instruction.  */	ARMword dest = 0;	/* Almost the DestBus.  */	ARMword temp;		/* Ubiquitous third hand.  */	ARMword pc = 0;		/* The address of the current instruction.  */	ARMword lhs;		/* Almost the ABus and BBus.  */	ARMword rhs;	ARMword decoded = 0;	/* Instruction pipeline.  */	ARMword loaded = 0;	ARMword decoded_addr=0;	ARMword loaded_addr=0;	ARMword have_bp=0;        static unsigned remote_interrupt_test_time=0;	/* Execute the next instruction.  */	if (state->NextInstr < PRIMEPIPE) {		decoded = state->decoded;		loaded = state->loaded;		pc = state->pc;		//chy 2006-04-12, for ICE debug		decoded_addr=state->decoded_addr;		loaded_addr=state->loaded_addr;	}	do {		/* Just keep going.  */		isize = INSN_SIZE;		switch (state->NextInstr) {		case SEQ:			/* Advance the pipeline, and an S cycle.  */			state->Reg[15] += isize;			pc += isize;			instr = decoded;			//chy 2006-04-12, for ICE debug			have_bp=ARMul_ICE_debug(state,instr,decoded_addr);			decoded = loaded;			decoded_addr=loaded_addr;			loaded = ARMul_LoadInstrS (state, pc + (isize * 2),						   isize);			loaded_addr=pc + (isize * 2);			if(have_bp) goto  TEST_EMULATE;			break;		case NONSEQ:			/* Advance the pipeline, and an N cycle.  */			state->Reg[15] += isize;			pc += isize;			instr = decoded;			//chy 2006-04-12, for ICE debug			have_bp=ARMul_ICE_debug(state,instr,decoded_addr);			decoded = loaded;			decoded_addr=loaded_addr;			loaded = ARMul_LoadInstrN (state, pc + (isize * 2),						   isize);			loaded_addr=pc + (isize * 2);			NORMALCYCLE;			if(have_bp) goto  TEST_EMULATE;			break;		case PCINCEDSEQ:			/* Program counter advanced, and an S cycle.  */			pc += isize;			instr = decoded;			//chy 2006-04-12, for ICE debug			have_bp=ARMul_ICE_debug(state,instr,decoded_addr);			decoded = loaded;			decoded_addr=loaded_addr;			loaded = ARMul_LoadInstrS (state, pc + (isize * 2),						   isize);			loaded_addr=pc + (isize * 2);			NORMALCYCLE;			if(have_bp) goto  TEST_EMULATE;			break;		case PCINCEDNONSEQ:			/* Program counter advanced, and an N cycle.  */			pc += isize;			instr = decoded;			//chy 2006-04-12, for ICE debug			have_bp=ARMul_ICE_debug(state,instr,decoded_addr);			decoded = loaded;			decoded_addr=loaded_addr;			loaded = ARMul_LoadInstrN (state, pc + (isize * 2),						   isize);			loaded_addr=pc + (isize * 2);			NORMALCYCLE;			if(have_bp) goto  TEST_EMULATE;			break;		case RESUME:			/* The program counter has been changed.  */			pc = state->Reg[15];#ifndef MODE32			pc = pc & R15PCBITS;#endif			state->Reg[15] = pc + (isize * 2);			state->Aborted = 0;			//chy 2004-05-25, fix bug provided by Carl van Schaik<cvansch@cse.unsw.EDU.AU>			state->AbortAddr = 1;			instr = ARMul_ReLoadInstr (state, pc, isize);			//chy 2006-04-12, for ICE debug			have_bp=ARMul_ICE_debug(state,instr,pc);			decoded =				ARMul_ReLoadInstr (state, pc + isize, isize);			decoded_addr=pc+isize;			loaded = ARMul_ReLoadInstr (state, pc + isize * 2,						    isize);			loaded_addr=pc + isize * 2;			NORMALCYCLE;			if(have_bp) goto  TEST_EMULATE;			break;		default:			/* The program counter has been changed.  */			pc = state->Reg[15];#ifndef MODE32			pc = pc & R15PCBITS;#endif			state->Reg[15] = pc + (isize * 2);			state->Aborted = 0;			//chy 2004-05-25, fix bug provided by Carl van Schaik<cvansch@cse.unsw.EDU.AU>			state->AbortAddr = 1;			instr = ARMul_LoadInstrN (state, pc, isize);			//chy 2006-04-12, for ICE debug			have_bp=ARMul_ICE_debug(state,instr,pc);			decoded =				ARMul_LoadInstrS (state, pc + (isize), isize);			decoded_addr=pc+isize;			loaded = ARMul_LoadInstrS (state, pc + (isize * 2),						   isize);			loaded_addr=pc + isize * 2;			NORMALCYCLE;			if(have_bp) goto  TEST_EMULATE;			break;		}		if (state->EventSet)			ARMul_EnvokeEvent (state);//2003-07-11 chy: for test		if (skyeye_config.log.logon >= 1) {			if (state->NumInstrs >= skyeye_config.log.start &&			    state->NumInstrs <= skyeye_config.log.end) {				static int mybegin = 0;				static int myinstrnum = 0;				if (mybegin == 0)					mybegin = 1;#if 0				if (state->NumInstrs == 3695) {					printf ("***********SKYEYE: numinstr = 3695\n");				}				static int mybeg2 = 0;				static int mybeg3 = 0;				static int mybeg4 = 0;				static int mybeg5 = 0;				if (pc == 0xa0008000) {					//mybegin=1;					printf ("************SKYEYE: real vmlinux begin now  numinstr is %llu  ****************\n", state->NumInstrs);				}				//chy 2003-09-02 test fiq				if (state->NumInstrs == 67347000) {					printf ("***********SKYEYE: numinstr = 67347000, begin log\n");					mybegin = 1;				}				if (pc == 0xc00087b4) {	//numinstr=67348714					mybegin = 1;					printf ("************SKYEYE: test irq now  numinstr is %llu  ****************\n", state->NumInstrs);				}				if (pc == 0xc00087b8) {	//in start_kernel::sti()					mybeg4 = 1;					printf ("************SKYEYE: startkerenl: sti now  numinstr is %llu  ********\n", state->NumInstrs);				}				//if(pc==0xc001e4f4||pc==0xc001e4f8||pc==0xc001e4fc||pc==0xc001e500||pc==0xffff0004) { //MRA instr				if (pc == 0xc001e500) {	//MRA instr					mybeg5 = 1;					printf ("************SKYEYE: MRA instr now  numinstr is %llu  ********\n", state->NumInstrs);				}				if (pc >= 0xc0000000 && mybeg2 == 0) {					mybeg2 = 1;					printf ("************SKYEYE: enable mmu&cache, now numinstr is %llu **************\n", state->NumInstrs);					SKYEYE_OUTREGS (stderr);					printf ("************************************************************************\n");				}				//chy 2003-09-01 test after tlb-flush 				if (pc == 0xc00261ac) {					//sleep(2);					mybeg3 = 1;

⌨️ 快捷键说明

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