18 changed files with 11356 additions and 0 deletions
-
14src/core/core.vcxproj
-
48src/core/core.vcxproj.filters
-
103src/core/src/arm/arm_regformat.h
-
83src/core/src/arm/armcpu.h
-
930src/core/src/arm/armdefs.h
-
6618src/core/src/arm/armemu.cpp
-
657src/core/src/arm/armemu.h
-
578src/core/src/arm/arminit.cpp
-
241src/core/src/arm/armmmu.cpp
-
254src/core/src/arm/armmmu.h
-
138src/core/src/arm/armos.h
-
1165src/core/src/arm/mmu/arm1176jzf_s_mmu.c
-
37src/core/src/arm/mmu/arm1176jzf_s_mmu.h
-
168src/core/src/arm/mmu/cache.h
-
55src/core/src/arm/mmu/rb.h
-
94src/core/src/arm/mmu/tlb.h
-
63src/core/src/arm/mmu/wb.h
-
110src/core/src/arm/skyeye_defs.h
@ -0,0 +1,103 @@ |
|||||
|
#ifndef __ARM_REGFORMAT_H__ |
||||
|
#define __ARM_REGFORMAT_H__ |
||||
|
|
||||
|
enum arm_regno{ |
||||
|
R0 = 0, |
||||
|
R1, |
||||
|
R2, |
||||
|
R3, |
||||
|
R4, |
||||
|
R5, |
||||
|
R6, |
||||
|
R7, |
||||
|
R8, |
||||
|
R9, |
||||
|
R10, |
||||
|
R11, |
||||
|
R12, |
||||
|
R13, |
||||
|
LR, |
||||
|
R15, //PC, |
||||
|
CPSR_REG, |
||||
|
SPSR_REG, |
||||
|
#if 1 |
||||
|
PHYS_PC, |
||||
|
R13_USR, |
||||
|
R14_USR, |
||||
|
R13_SVC, |
||||
|
R14_SVC, |
||||
|
R13_ABORT, |
||||
|
R14_ABORT, |
||||
|
R13_UNDEF, |
||||
|
R14_UNDEF, |
||||
|
R13_IRQ, |
||||
|
R14_IRQ, |
||||
|
R8_FIRQ, |
||||
|
R9_FIRQ, |
||||
|
R10_FIRQ, |
||||
|
R11_FIRQ, |
||||
|
R12_FIRQ, |
||||
|
R13_FIRQ, |
||||
|
R14_FIRQ, |
||||
|
SPSR_INVALID1, |
||||
|
SPSR_INVALID2, |
||||
|
SPSR_SVC, |
||||
|
SPSR_ABORT, |
||||
|
SPSR_UNDEF, |
||||
|
SPSR_IRQ, |
||||
|
SPSR_FIRQ, |
||||
|
MODE_REG, /* That is the cpsr[4 : 0], just for calculation easily */ |
||||
|
BANK_REG, |
||||
|
EXCLUSIVE_TAG, |
||||
|
EXCLUSIVE_STATE, |
||||
|
EXCLUSIVE_RESULT, |
||||
|
CP15_BASE, |
||||
|
CP15_C0 = CP15_BASE, |
||||
|
CP15_C0_C0 = CP15_C0, |
||||
|
CP15_MAIN_ID = CP15_C0_C0, |
||||
|
CP15_CACHE_TYPE, |
||||
|
CP15_TCM_STATUS, |
||||
|
CP15_TLB_TYPE, |
||||
|
CP15_C0_C1, |
||||
|
CP15_PROCESSOR_FEATURE_0 = CP15_C0_C1, |
||||
|
CP15_PROCESSOR_FEATURE_1, |
||||
|
CP15_DEBUG_FEATURE_0, |
||||
|
CP15_AUXILIARY_FEATURE_0, |
||||
|
CP15_C1_C0, |
||||
|
CP15_CONTROL = CP15_C1_C0, |
||||
|
CP15_AUXILIARY_CONTROL, |
||||
|
CP15_COPROCESSOR_ACCESS_CONTROL, |
||||
|
CP15_C2, |
||||
|
CP15_C2_C0 = CP15_C2, |
||||
|
CP15_TRANSLATION_BASE = CP15_C2_C0, |
||||
|
CP15_TRANSLATION_BASE_TABLE_0 = CP15_TRANSLATION_BASE, |
||||
|
CP15_TRANSLATION_BASE_TABLE_1, |
||||
|
CP15_TRANSLATION_BASE_CONTROL, |
||||
|
CP15_DOMAIN_ACCESS_CONTROL, |
||||
|
CP15_RESERVED, |
||||
|
/* Fault status */ |
||||
|
CP15_FAULT_STATUS, |
||||
|
CP15_INSTR_FAULT_STATUS, |
||||
|
CP15_COMBINED_DATA_FSR = CP15_FAULT_STATUS, |
||||
|
CP15_INST_FSR, |
||||
|
/* Fault Address register */ |
||||
|
CP15_FAULT_ADDRESS, |
||||
|
CP15_COMBINED_DATA_FAR = CP15_FAULT_ADDRESS, |
||||
|
CP15_WFAR, |
||||
|
CP15_IFAR, |
||||
|
CP15_PID, |
||||
|
CP15_CONTEXT_ID, |
||||
|
CP15_THREAD_URO, |
||||
|
CP15_TLB_FAULT_ADDR, /* defined by SkyEye */ |
||||
|
CP15_TLB_FAULT_STATUS, /* defined by SkyEye */ |
||||
|
/* VFP registers */ |
||||
|
VFP_BASE, |
||||
|
VFP_FPSID = VFP_BASE, |
||||
|
VFP_FPSCR, |
||||
|
VFP_FPEXC, |
||||
|
#endif |
||||
|
MAX_REG_NUM, |
||||
|
}; |
||||
|
|
||||
|
#define VFP_OFFSET(x) (x - VFP_BASE) |
||||
|
#endif |
||||
@ -0,0 +1,83 @@ |
|||||
|
/* |
||||
|
* arm |
||||
|
* armcpu.h |
||||
|
* |
||||
|
* Copyright (C) 2003, 2004 Sebastian Biallas (sb@biallas.net) |
||||
|
* |
||||
|
* This program is free software; you can redistribute it and/or modify |
||||
|
* it under the terms of the GNU General Public License version 2 as |
||||
|
* published by the Free Software Foundation. |
||||
|
* |
||||
|
* 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., 675 Mass Ave, Cambridge, MA 02139, USA. |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __ARM_CPU_H__ |
||||
|
#define __ARM_CPU_H__ |
||||
|
//#include <skyeye_thread.h> |
||||
|
//#include <skyeye_obj.h> |
||||
|
//#include <skyeye_mach.h> |
||||
|
//#include <skyeye_exec.h> |
||||
|
|
||||
|
#include <stddef.h> |
||||
|
#include <stdio.h> |
||||
|
|
||||
|
#include "thread.h" |
||||
|
|
||||
|
|
||||
|
typedef struct ARM_CPU_State_s { |
||||
|
ARMul_State * core; |
||||
|
uint32_t core_num; |
||||
|
/* The core id that boot from |
||||
|
*/ |
||||
|
uint32_t boot_core_id; |
||||
|
}ARM_CPU_State; |
||||
|
|
||||
|
//static ARM_CPU_State* get_current_cpu(){ |
||||
|
// machine_config_t* mach = get_current_mach(); |
||||
|
// /* Casting a conf_obj_t to ARM_CPU_State type */ |
||||
|
// ARM_CPU_State* cpu = (ARM_CPU_State*)mach->cpu_data->obj; |
||||
|
// |
||||
|
// return cpu; |
||||
|
//} |
||||
|
|
||||
|
/** |
||||
|
* @brief Get the core instance boot from |
||||
|
* |
||||
|
* @return |
||||
|
*/ |
||||
|
//static ARMul_State* get_boot_core(){ |
||||
|
// ARM_CPU_State* cpu = get_current_cpu(); |
||||
|
// return &cpu->core[cpu->boot_core_id]; |
||||
|
//} |
||||
|
/** |
||||
|
* @brief Get the instance of running core |
||||
|
* |
||||
|
* @return the core instance |
||||
|
*/ |
||||
|
//static ARMul_State* get_current_core(){ |
||||
|
// /* Casting a conf_obj_t to ARM_CPU_State type */ |
||||
|
// int id = Common::CurrentThreadId(); |
||||
|
// /* If thread is not in running mode, we should give the boot core */ |
||||
|
// if(get_thread_state(id) != Running_state){ |
||||
|
// return get_boot_core(); |
||||
|
// } |
||||
|
// /* Judge if we are running in paralell or sequenial */ |
||||
|
// if(thread_exist(id)){ |
||||
|
// conf_object_t* conf_obj = get_current_exec_priv(id); |
||||
|
// return (ARMul_State*)get_cast_conf_obj(conf_obj, "arm_core_t"); |
||||
|
// } |
||||
|
// |
||||
|
// return NULL; |
||||
|
//} |
||||
|
|
||||
|
#define CURRENT_CORE get_current_core() |
||||
|
|
||||
|
#endif |
||||
|
|
||||
@ -0,0 +1,930 @@ |
|||||
|
/* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator. |
||||
|
Copyright (C) 1994 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. */ |
||||
|
|
||||
|
#ifndef _ARMDEFS_H_ |
||||
|
#define _ARMDEFS_H_ |
||||
|
|
||||
|
#include <stdio.h> |
||||
|
#include <stdlib.h> |
||||
|
#include <errno.h> |
||||
|
|
||||
|
//teawater add for arm2x86 2005.02.14------------------------------------------- |
||||
|
// koodailar remove it for mingw 2005.12.18---------------- |
||||
|
//anthonylee modify it for portable 2007.01.30 |
||||
|
//#include "portable/mman.h" |
||||
|
|
||||
|
#include "arm_regformat.h" |
||||
|
#include "platform.h" |
||||
|
#include "skyeye_defs.h" |
||||
|
|
||||
|
//AJ2D-------------------------------------------------------------------------- |
||||
|
|
||||
|
//teawater add for arm2x86 2005.07.03------------------------------------------- |
||||
|
|
||||
|
#include <sys/types.h> |
||||
|
#include <stdio.h> |
||||
|
#include <stdlib.h> |
||||
|
#include <string.h> |
||||
|
#if EMU_PLATFORM == PLATFORM_LINUX |
||||
|
#include <unistd.h> |
||||
|
#endif |
||||
|
#include <errno.h> |
||||
|
#include <sys/stat.h> |
||||
|
#include <fcntl.h> |
||||
|
|
||||
|
//#include <memory_space.h> |
||||
|
//AJ2D-------------------------------------------------------------------------- |
||||
|
#if 0 |
||||
|
#if 0 |
||||
|
#define DIFF_STATE 1 |
||||
|
#define __FOLLOW_MODE__ 0 |
||||
|
#else |
||||
|
#define DIFF_STATE 0 |
||||
|
#define __FOLLOW_MODE__ 1 |
||||
|
#endif |
||||
|
#endif |
||||
|
|
||||
|
#ifndef FALSE |
||||
|
#define FALSE 0 |
||||
|
#define TRUE 1 |
||||
|
#endif |
||||
|
|
||||
|
#define LOW 0 |
||||
|
#define HIGH 1 |
||||
|
#define LOWHIGH 1 |
||||
|
#define HIGHLOW 2 |
||||
|
|
||||
|
#ifndef u8 |
||||
|
#define u8 unsigned char |
||||
|
#define u16 unsigned short |
||||
|
#define u32 unsigned int |
||||
|
#define u64 unsigned long long |
||||
|
#endif /*u8 */ |
||||
|
|
||||
|
//teawater add DBCT_TEST_SPEED 2005.10.04--------------------------------------- |
||||
|
#include <signal.h> |
||||
|
|
||||
|
#include "platform.h" |
||||
|
|
||||
|
#if EMU_PLATFORM == PLATFORM_LINUX |
||||
|
#include <sys/time.h> |
||||
|
#endif |
||||
|
|
||||
|
//#define DBCT_TEST_SPEED |
||||
|
#define DBCT_TEST_SPEED_SEC 10 |
||||
|
//AJ2D-------------------------------------------------------------------------- |
||||
|
|
||||
|
//teawater add compile switch for DBCT GDB RSP function 2005.10.21-------------- |
||||
|
//#define DBCT_GDBRSP |
||||
|
//AJ2D-------------------------------------------------------------------------- |
||||
|
|
||||
|
//#include <skyeye_defs.h> |
||||
|
//#include <skyeye_types.h> |
||||
|
|
||||
|
#define ARM_BYTE_TYPE 0 |
||||
|
#define ARM_HALFWORD_TYPE 1 |
||||
|
#define ARM_WORD_TYPE 2 |
||||
|
|
||||
|
//the define of cachetype |
||||
|
#define NONCACHE 0 |
||||
|
#define DATACACHE 1 |
||||
|
#define INSTCACHE 2 |
||||
|
|
||||
|
#ifndef __STDC__ |
||||
|
typedef char *VoidStar; |
||||
|
#endif |
||||
|
|
||||
|
typedef unsigned long long ARMdword; /* must be 64 bits wide */ |
||||
|
typedef unsigned int ARMword; /* must be 32 bits wide */ |
||||
|
typedef unsigned char ARMbyte; /* must be 8 bits wide */ |
||||
|
typedef unsigned short ARMhword; /* must be 16 bits wide */ |
||||
|
typedef struct ARMul_State ARMul_State; |
||||
|
typedef struct ARMul_io ARMul_io; |
||||
|
typedef struct ARMul_Energy ARMul_Energy; |
||||
|
|
||||
|
//teawater add for arm2x86 2005.06.24------------------------------------------- |
||||
|
#include <stdint.h> |
||||
|
//AJ2D-------------------------------------------------------------------------- |
||||
|
/* |
||||
|
//chy 2005-05-11 |
||||
|
#ifndef __CYGWIN__ |
||||
|
//teawater add for arm2x86 2005.02.14------------------------------------------- |
||||
|
typedef unsigned char uint8_t; |
||||
|
typedef unsigned short uint16_t; |
||||
|
typedef unsigned int u32; |
||||
|
#if defined (__x86_64__) |
||||
|
typedef unsigned long uint64_t; |
||||
|
#else |
||||
|
typedef unsigned long long uint64_t; |
||||
|
#endif |
||||
|
////AJ2D-------------------------------------------------------------------------- |
||||
|
#endif |
||||
|
*/ |
||||
|
|
||||
|
#include "armmmu.h" |
||||
|
//#include "lcd/skyeye_lcd.h" |
||||
|
|
||||
|
|
||||
|
//#include "skyeye.h" |
||||
|
//#include "skyeye_device.h" |
||||
|
//#include "net/skyeye_net.h" |
||||
|
//#include "skyeye_config.h" |
||||
|
|
||||
|
|
||||
|
typedef unsigned ARMul_CPInits (ARMul_State * state); |
||||
|
typedef unsigned ARMul_CPExits (ARMul_State * state); |
||||
|
typedef unsigned ARMul_LDCs (ARMul_State * state, unsigned type, |
||||
|
ARMword instr, ARMword value); |
||||
|
typedef unsigned ARMul_STCs (ARMul_State * state, unsigned type, |
||||
|
ARMword instr, ARMword * value); |
||||
|
typedef unsigned ARMul_MRCs (ARMul_State * state, unsigned type, |
||||
|
ARMword instr, ARMword * value); |
||||
|
typedef unsigned ARMul_MCRs (ARMul_State * state, unsigned type, |
||||
|
ARMword instr, ARMword value); |
||||
|
typedef unsigned ARMul_MRRCs (ARMul_State * state, unsigned type, |
||||
|
ARMword instr, ARMword * value1, ARMword * value2); |
||||
|
typedef unsigned ARMul_MCRRs (ARMul_State * state, unsigned type, |
||||
|
ARMword instr, ARMword value1, ARMword value2); |
||||
|
typedef unsigned ARMul_CDPs (ARMul_State * state, unsigned type, |
||||
|
ARMword instr); |
||||
|
typedef unsigned ARMul_CPReads (ARMul_State * state, unsigned reg, |
||||
|
ARMword * value); |
||||
|
typedef unsigned ARMul_CPWrites (ARMul_State * state, unsigned reg, |
||||
|
ARMword value); |
||||
|
|
||||
|
|
||||
|
//added by ksh,2004-3-5 |
||||
|
struct ARMul_io |
||||
|
{ |
||||
|
ARMword *instr; //to display the current interrupt state |
||||
|
ARMword *net_flag; //to judge if network is enabled |
||||
|
ARMword *net_int; //netcard interrupt |
||||
|
|
||||
|
//ywc,2004-04-01 |
||||
|
ARMword *ts_int; |
||||
|
ARMword *ts_is_enable; |
||||
|
ARMword *ts_addr_begin; |
||||
|
ARMword *ts_addr_end; |
||||
|
ARMword *ts_buffer; |
||||
|
}; |
||||
|
|
||||
|
/* added by ksh,2004-11-26,some energy profiling */ |
||||
|
struct ARMul_Energy |
||||
|
{ |
||||
|
int energy_prof; /* <tktan> BUG200103282109 : for energy profiling */ |
||||
|
int enable_func_energy; /* <tktan> BUG200105181702 */ |
||||
|
char *func_energy; |
||||
|
int func_display; /* <tktan> BUG200103311509 : for function call display */ |
||||
|
int func_disp_start; /* <tktan> BUG200104191428 : to start func profiling */ |
||||
|
char *start_func; /* <tktan> BUG200104191428 */ |
||||
|
|
||||
|
FILE *outfile; /* <tktan> BUG200105201531 : direct console to file */ |
||||
|
long long tcycle, pcycle; |
||||
|
float t_energy; |
||||
|
void *cur_task; /* <tktan> BUG200103291737 */ |
||||
|
long long t_mem_cycle, t_idle_cycle, t_uart_cycle; |
||||
|
long long p_mem_cycle, p_idle_cycle, p_uart_cycle; |
||||
|
long long p_io_update_tcycle; |
||||
|
/*record CCCR,to get current core frequency */ |
||||
|
ARMword cccr; |
||||
|
}; |
||||
|
#if 0 |
||||
|
#define MAX_BANK 8 |
||||
|
#define MAX_STR 1024 |
||||
|
|
||||
|
typedef struct mem_bank |
||||
|
{ |
||||
|
ARMword (*read_byte) (ARMul_State * state, ARMword addr); |
||||
|
void (*write_byte) (ARMul_State * state, ARMword addr, ARMword data); |
||||
|
ARMword (*read_halfword) (ARMul_State * state, ARMword addr); |
||||
|
void (*write_halfword) (ARMul_State * state, ARMword addr, |
||||
|
ARMword data); |
||||
|
ARMword (*read_word) (ARMul_State * state, ARMword addr); |
||||
|
void (*write_word) (ARMul_State * state, ARMword addr, ARMword data); |
||||
|
unsigned int addr, len; |
||||
|
char filename[MAX_STR]; |
||||
|
unsigned type; //chy 2003-09-21: maybe io,ram,rom |
||||
|
} mem_bank_t; |
||||
|
typedef struct |
||||
|
{ |
||||
|
int bank_num; |
||||
|
int current_num; /*current num of bank */ |
||||
|
mem_bank_t mem_banks[MAX_BANK]; |
||||
|
} mem_config_t; |
||||
|
#endif |
||||
|
#define VFP_REG_NUM 64 |
||||
|
struct ARMul_State |
||||
|
{ |
||||
|
ARMword Emulate; /* to start and stop emulation */ |
||||
|
unsigned EndCondition; /* reason for stopping */ |
||||
|
unsigned ErrorCode; /* type of illegal instruction */ |
||||
|
|
||||
|
/* Order of the following register should not be modified */ |
||||
|
ARMword Reg[16]; /* the current register file */ |
||||
|
ARMword Cpsr; /* the current psr */ |
||||
|
ARMword Spsr_copy; |
||||
|
ARMword phys_pc; |
||||
|
ARMword Reg_usr[2]; |
||||
|
ARMword Reg_svc[2]; /* R13_SVC R14_SVC */ |
||||
|
ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */ |
||||
|
ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */ |
||||
|
ARMword Reg_irq[2]; /* R13_IRQ R14_IRQ */ |
||||
|
ARMword Reg_firq[7]; /* R8---R14 FIRQ */ |
||||
|
ARMword Spsr[7]; /* the exception psr's */ |
||||
|
ARMword Mode; /* the current mode */ |
||||
|
ARMword Bank; /* the current register bank */ |
||||
|
ARMword exclusive_tag; |
||||
|
ARMword exclusive_state; |
||||
|
ARMword exclusive_result; |
||||
|
ARMword CP15[VFP_BASE - CP15_BASE]; |
||||
|
ARMword VFP[3]; /* FPSID, FPSCR, and FPEXC */ |
||||
|
/* VFPv2 and VFPv3-D16 has 16 doubleword registers (D0-D16 or S0-S31). |
||||
|
VFPv3-D32/ASIMD may have up to 32 doubleword registers (D0-D31), |
||||
|
and only 32 singleword registers are accessible (S0-S31). */ |
||||
|
ARMword ExtReg[VFP_REG_NUM]; |
||||
|
/* ---- End of the ordered registers ---- */ |
||||
|
|
||||
|
ARMword RegBank[7][16]; /* all the registers */ |
||||
|
//chy:2003-08-19, used in arm xscale |
||||
|
/* 40 bit accumulator. We always keep this 64 bits wide, |
||||
|
and move only 40 bits out of it in an MRA insn. */ |
||||
|
ARMdword Accumulator; |
||||
|
|
||||
|
ARMword NFlag, ZFlag, CFlag, VFlag, IFFlags; /* dummy flags for speed */ |
||||
|
unsigned long long int icounter, debug_icounter, kernel_icounter; |
||||
|
unsigned int shifter_carry_out; |
||||
|
//ARMword translate_pc; |
||||
|
|
||||
|
/* add armv6 flags dyf:2010-08-09 */ |
||||
|
ARMword GEFlag, EFlag, AFlag, QFlags; |
||||
|
//chy:2003-08-19, used in arm v5e|xscale |
||||
|
ARMword SFlag; |
||||
|
#ifdef MODET |
||||
|
ARMword TFlag; /* Thumb state */ |
||||
|
#endif |
||||
|
ARMword instr, pc, temp; /* saved register state */ |
||||
|
ARMword loaded, decoded; /* saved pipeline state */ |
||||
|
//chy 2006-04-12 for ICE breakpoint |
||||
|
ARMword loaded_addr, decoded_addr; /* saved pipeline state addr*/ |
||||
|
unsigned int NumScycles, NumNcycles, NumIcycles, NumCcycles, NumFcycles; /* emulated cycles used */ |
||||
|
unsigned long long NumInstrs; /* the number of instructions executed */ |
||||
|
unsigned NextInstr; |
||||
|
unsigned VectorCatch; /* caught exception mask */ |
||||
|
unsigned CallDebug; /* set to call the debugger */ |
||||
|
unsigned CanWatch; /* set by memory interface if its willing to suffer the |
||||
|
overhead of checking for watchpoints on each memory |
||||
|
access */ |
||||
|
unsigned int StopHandle; |
||||
|
|
||||
|
char *CommandLine; /* Command Line from ARMsd */ |
||||
|
|
||||
|
ARMul_CPInits *CPInit[16]; /* coprocessor initialisers */ |
||||
|
ARMul_CPExits *CPExit[16]; /* coprocessor finalisers */ |
||||
|
ARMul_LDCs *LDC[16]; /* LDC instruction */ |
||||
|
ARMul_STCs *STC[16]; /* STC instruction */ |
||||
|
ARMul_MRCs *MRC[16]; /* MRC instruction */ |
||||
|
ARMul_MCRs *MCR[16]; /* MCR instruction */ |
||||
|
ARMul_MRRCs *MRRC[16]; /* MRRC instruction */ |
||||
|
ARMul_MCRRs *MCRR[16]; /* MCRR instruction */ |
||||
|
ARMul_CDPs *CDP[16]; /* CDP instruction */ |
||||
|
ARMul_CPReads *CPRead[16]; /* Read CP register */ |
||||
|
ARMul_CPWrites *CPWrite[16]; /* Write CP register */ |
||||
|
unsigned char *CPData[16]; /* Coprocessor data */ |
||||
|
unsigned char const *CPRegWords[16]; /* map of coprocessor register sizes */ |
||||
|
|
||||
|
unsigned EventSet; /* the number of events in the queue */ |
||||
|
unsigned int Now; /* time to the nearest cycle */ |
||||
|
struct EventNode **EventPtr; /* the event list */ |
||||
|
|
||||
|
unsigned Debug; /* show instructions as they are executed */ |
||||
|
unsigned NresetSig; /* reset the processor */ |
||||
|
unsigned NfiqSig; |
||||
|
unsigned NirqSig; |
||||
|
|
||||
|
unsigned abortSig; |
||||
|
unsigned NtransSig; |
||||
|
unsigned bigendSig; |
||||
|
unsigned prog32Sig; |
||||
|
unsigned data32Sig; |
||||
|
unsigned syscallSig; |
||||
|
|
||||
|
/* 2004-05-09 chy |
||||
|
---------------------------------------------------------- |
||||
|
read ARM Architecture Reference Manual |
||||
|
2.6.5 Data Abort |
||||
|
There are three Abort Model in ARM arch. |
||||
|
|
||||
|
Early Abort Model: used in some ARMv3 and earlier implementations. In this |
||||
|
model, base register wirteback occurred for LDC,LDM,STC,STM instructions, and |
||||
|
the base register was unchanged for all other instructions. (oldest) |
||||
|
|
||||
|
Base Restored Abort Model: If a Data Abort occurs in an instruction which |
||||
|
specifies base register writeback, the value in the base register is |
||||
|
unchanged. (strongarm, xscale) |
||||
|
|
||||
|
Base Updated Abort Model: If a Data Abort occurs in an instruction which |
||||
|
specifies base register writeback, the base register writeback still occurs. |
||||
|
(arm720T) |
||||
|
|
||||
|
read PART B |
||||
|
chap2 The System Control Coprocessor CP15 |
||||
|
2.4 Register1:control register |
||||
|
L(bit 6): in some ARMv3 and earlier implementations, the abort model of the |
||||
|
processor could be configured: |
||||
|
0=early Abort Model Selected(now obsolete) |
||||
|
1=Late Abort Model selceted(same as Base Updated Abort Model) |
||||
|
|
||||
|
on later processors, this bit reads as 1 and ignores writes. |
||||
|
------------------------------------------------------------- |
||||
|
So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model) |
||||
|
if lateabtSig=0, then it means Base Restored Abort Model |
||||
|
*/ |
||||
|
unsigned lateabtSig; |
||||
|
|
||||
|
ARMword Vector; /* synthesize aborts in cycle modes */ |
||||
|
ARMword Aborted; /* sticky flag for aborts */ |
||||
|
ARMword Reseted; /* sticky flag for Reset */ |
||||
|
ARMword Inted, LastInted; /* sticky flags for interrupts */ |
||||
|
ARMword Base; /* extra hand for base writeback */ |
||||
|
ARMword AbortAddr; /* to keep track of Prefetch aborts */ |
||||
|
|
||||
|
const struct Dbg_HostosInterface *hostif; |
||||
|
|
||||
|
int verbose; /* non-zero means print various messages like the banner */ |
||||
|
|
||||
|
mmu_state_t mmu; |
||||
|
int mmu_inited; |
||||
|
//mem_state_t mem; |
||||
|
/*remove io_state to skyeye_mach_*.c files */ |
||||
|
//io_state_t io; |
||||
|
/* point to a interrupt pending register. now for skyeye-ne2k.c |
||||
|
* later should move somewhere. e.g machine_config_t*/ |
||||
|
|
||||
|
|
||||
|
//chy: 2003-08-11, for different arm core type |
||||
|
unsigned is_v4; /* Are we emulating a v4 architecture (or higher) ? */ |
||||
|
unsigned is_v5; /* Are we emulating a v5 architecture ? */ |
||||
|
unsigned is_v5e; /* Are we emulating a v5e architecture ? */ |
||||
|
unsigned is_v6; /* Are we emulating a v6 architecture ? */ |
||||
|
unsigned is_v7; /* Are we emulating a v7 architecture ? */ |
||||
|
unsigned is_XScale; /* Are we emulating an XScale architecture ? */ |
||||
|
unsigned is_iWMMXt; /* Are we emulating an iWMMXt co-processor ? */ |
||||
|
unsigned is_ep9312; /* Are we emulating a Cirrus Maverick co-processor ? */ |
||||
|
//chy 2005-09-19 |
||||
|
unsigned is_pxa27x; /* Are we emulating a Intel PXA27x co-processor ? */ |
||||
|
//chy: seems only used in xscale's CP14 |
||||
|
unsigned int LastTime; /* Value of last call to ARMul_Time() */ |
||||
|
ARMword CP14R0_CCD; /* used to count 64 clock cycles with CP14 R0 bit 3 set */ |
||||
|
|
||||
|
|
||||
|
//added by ksh:for handle different machs io 2004-3-5 |
||||
|
ARMul_io mach_io; |
||||
|
|
||||
|
/*added by ksh,2004-11-26,some energy profiling*/ |
||||
|
ARMul_Energy energy; |
||||
|
|
||||
|
//teawater add for next_dis 2004.10.27----------------------- |
||||
|
int disassemble; |
||||
|
//AJ2D------------------------------------------ |
||||
|
|
||||
|
//teawater add for arm2x86 2005.02.15------------------------------------------- |
||||
|
u32 trap; |
||||
|
u32 tea_break_addr; |
||||
|
u32 tea_break_ok; |
||||
|
int tea_pc; |
||||
|
//AJ2D-------------------------------------------------------------------------- |
||||
|
//teawater add for arm2x86 2005.07.03------------------------------------------- |
||||
|
|
||||
|
/* |
||||
|
* 2007-01-24 removed the term-io functions by Anthony Lee, |
||||
|
* moved to "device/uart/skyeye_uart_stdio.c". |
||||
|
*/ |
||||
|
|
||||
|
//AJ2D-------------------------------------------------------------------------- |
||||
|
//teawater add for arm2x86 2005.07.05------------------------------------------- |
||||
|
//arm_arm A2-18 |
||||
|
int abort_model; //0 Base Restored Abort Model, 1 the Early Abort Model, 2 Base Updated Abort Model |
||||
|
//AJ2D-------------------------------------------------------------------------- |
||||
|
//teawater change for return if running tb dirty 2005.07.09--------------------- |
||||
|
void *tb_now; |
||||
|
//AJ2D-------------------------------------------------------------------------- |
||||
|
|
||||
|
//teawater add for record reg value to ./reg.txt 2005.07.10--------------------- |
||||
|
FILE *tea_reg_fd; |
||||
|
//AJ2D-------------------------------------------------------------------------- |
||||
|
|
||||
|
/*added by ksh in 2005-10-1*/ |
||||
|
cpu_config_t *cpu; |
||||
|
//mem_config_t *mem_bank; |
||||
|
|
||||
|
/* added LPC remap function */ |
||||
|
int vector_remap_flag; |
||||
|
u32 vector_remap_addr; |
||||
|
u32 vector_remap_size; |
||||
|
|
||||
|
u32 step; |
||||
|
u32 cycle; |
||||
|
int stop_simulator; |
||||
|
conf_object_t *dyncom_cpu; |
||||
|
//teawater add DBCT_TEST_SPEED 2005.10.04--------------------------------------- |
||||
|
#ifdef DBCT_TEST_SPEED |
||||
|
uint64_t instr_count; |
||||
|
#endif //DBCT_TEST_SPEED |
||||
|
// FILE * state_log; |
||||
|
//diff log |
||||
|
//#if DIFF_STATE |
||||
|
FILE * state_log; |
||||
|
//#endif |
||||
|
/* monitored memory for exclusice access */ |
||||
|
ARMword exclusive_tag_array[128]; |
||||
|
/* 1 means exclusive access and 0 means open access */ |
||||
|
ARMword exclusive_access_state; |
||||
|
|
||||
|
memory_space_intf space; |
||||
|
u32 CurrInstr; |
||||
|
u32 last_pc; /* the last pc executed */ |
||||
|
u32 last_instr; /* the last inst executed */ |
||||
|
u32 WriteAddr[17]; |
||||
|
u32 WriteData[17]; |
||||
|
u32 WritePc[17]; |
||||
|
u32 CurrWrite; |
||||
|
}; |
||||
|
#define DIFF_WRITE 0 |
||||
|
|
||||
|
typedef ARMul_State arm_core_t; |
||||
|
#define ResetPin NresetSig |
||||
|
#define FIQPin NfiqSig |
||||
|
#define IRQPin NirqSig |
||||
|
#define AbortPin abortSig |
||||
|
#define TransPin NtransSig |
||||
|
#define BigEndPin bigendSig |
||||
|
#define Prog32Pin prog32Sig |
||||
|
#define Data32Pin data32Sig |
||||
|
#define LateAbortPin lateabtSig |
||||
|
|
||||
|
/***************************************************************************\ |
||||
|
* Types of ARM we know about * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
/* The bitflags */ |
||||
|
#define ARM_Fix26_Prop 0x01 |
||||
|
#define ARM_Nexec_Prop 0x02 |
||||
|
#define ARM_Debug_Prop 0x10 |
||||
|
#define ARM_Isync_Prop ARM_Debug_Prop |
||||
|
#define ARM_Lock_Prop 0x20 |
||||
|
//chy 2003-08-11 |
||||
|
#define ARM_v4_Prop 0x40 |
||||
|
#define ARM_v5_Prop 0x80 |
||||
|
/*jeff.du 2010-08-05 */ |
||||
|
#define ARM_v6_Prop 0xc0 |
||||
|
|
||||
|
#define ARM_v5e_Prop 0x100 |
||||
|
#define ARM_XScale_Prop 0x200 |
||||
|
#define ARM_ep9312_Prop 0x400 |
||||
|
#define ARM_iWMMXt_Prop 0x800 |
||||
|
//chy 2005-09-19 |
||||
|
#define ARM_PXA27X_Prop 0x1000 |
||||
|
#define ARM_v7_Prop 0x2000 |
||||
|
|
||||
|
/* ARM2 family */ |
||||
|
#define ARM2 (ARM_Fix26_Prop) |
||||
|
#define ARM2as ARM2 |
||||
|
#define ARM61 ARM2 |
||||
|
#define ARM3 ARM2 |
||||
|
|
||||
|
#ifdef ARM60 /* previous definition in armopts.h */ |
||||
|
#undef ARM60 |
||||
|
#endif |
||||
|
|
||||
|
/* ARM6 family */ |
||||
|
#define ARM6 (ARM_Lock_Prop) |
||||
|
#define ARM60 ARM6 |
||||
|
#define ARM600 ARM6 |
||||
|
#define ARM610 ARM6 |
||||
|
#define ARM620 ARM6 |
||||
|
|
||||
|
|
||||
|
/***************************************************************************\ |
||||
|
* Macros to extract instruction fields * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
#define BIT(n) ( (ARMword)(instr>>(n))&1) /* bit n of instruction */ |
||||
|
#define BITS(m,n) ( (ARMword)(instr<<(31-(n))) >> ((31-(n))+(m)) ) /* bits m to n of instr */ |
||||
|
#define TOPBITS(n) (instr >> (n)) /* bits 31 to n of instr */ |
||||
|
|
||||
|
/***************************************************************************\ |
||||
|
* The hardware vector addresses * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
#define ARMResetV 0L |
||||
|
#define ARMUndefinedInstrV 4L |
||||
|
#define ARMSWIV 8L |
||||
|
#define ARMPrefetchAbortV 12L |
||||
|
#define ARMDataAbortV 16L |
||||
|
#define ARMAddrExceptnV 20L |
||||
|
#define ARMIRQV 24L |
||||
|
#define ARMFIQV 28L |
||||
|
#define ARMErrorV 32L /* This is an offset, not an address ! */ |
||||
|
|
||||
|
#define ARMul_ResetV ARMResetV |
||||
|
#define ARMul_UndefinedInstrV ARMUndefinedInstrV |
||||
|
#define ARMul_SWIV ARMSWIV |
||||
|
#define ARMul_PrefetchAbortV ARMPrefetchAbortV |
||||
|
#define ARMul_DataAbortV ARMDataAbortV |
||||
|
#define ARMul_AddrExceptnV ARMAddrExceptnV |
||||
|
#define ARMul_IRQV ARMIRQV |
||||
|
#define ARMul_FIQV ARMFIQV |
||||
|
|
||||
|
/***************************************************************************\ |
||||
|
* Mode and Bank Constants * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
#define USER26MODE 0L |
||||
|
#define FIQ26MODE 1L |
||||
|
#define IRQ26MODE 2L |
||||
|
#define SVC26MODE 3L |
||||
|
#define USER32MODE 16L |
||||
|
#define FIQ32MODE 17L |
||||
|
#define IRQ32MODE 18L |
||||
|
#define SVC32MODE 19L |
||||
|
#define ABORT32MODE 23L |
||||
|
#define UNDEF32MODE 27L |
||||
|
//chy 2006-02-15 add system32 mode |
||||
|
#define SYSTEM32MODE 31L |
||||
|
|
||||
|
#define ARM32BITMODE (state->Mode > 3) |
||||
|
#define ARM26BITMODE (state->Mode <= 3) |
||||
|
#define ARMMODE (state->Mode) |
||||
|
#define ARMul_MODEBITS 0x1fL |
||||
|
#define ARMul_MODE32BIT ARM32BITMODE |
||||
|
#define ARMul_MODE26BIT ARM26BITMODE |
||||
|
|
||||
|
#define USERBANK 0 |
||||
|
#define FIQBANK 1 |
||||
|
#define IRQBANK 2 |
||||
|
#define SVCBANK 3 |
||||
|
#define ABORTBANK 4 |
||||
|
#define UNDEFBANK 5 |
||||
|
#define DUMMYBANK 6 |
||||
|
#define SYSTEMBANK USERBANK |
||||
|
#define BANK_CAN_ACCESS_SPSR(bank) \ |
||||
|
((bank) != USERBANK && (bank) != SYSTEMBANK && (bank) != DUMMYBANK) |
||||
|
|
||||
|
|
||||
|
/***************************************************************************\ |
||||
|
* Definitons of things in the emulator * |
||||
|
\***************************************************************************/ |
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
extern void ARMul_EmulateInit (void); |
||||
|
extern void ARMul_Reset (ARMul_State * state); |
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
extern ARMul_State *ARMul_NewState (ARMul_State * state); |
||||
|
extern ARMword ARMul_DoProg (ARMul_State * state); |
||||
|
extern ARMword ARMul_DoInstr (ARMul_State * state); |
||||
|
/***************************************************************************\ |
||||
|
* Definitons of things for event handling * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
extern void ARMul_ScheduleEvent (ARMul_State * state, unsigned int delay, |
||||
|
unsigned (*func) ()); |
||||
|
extern void ARMul_EnvokeEvent (ARMul_State * state); |
||||
|
extern unsigned int ARMul_Time (ARMul_State * state); |
||||
|
|
||||
|
/***************************************************************************\ |
||||
|
* Useful support routines * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
extern ARMword ARMul_GetReg (ARMul_State * state, unsigned mode, |
||||
|
unsigned reg); |
||||
|
extern void ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, |
||||
|
ARMword value); |
||||
|
extern ARMword ARMul_GetPC (ARMul_State * state); |
||||
|
extern ARMword ARMul_GetNextPC (ARMul_State * state); |
||||
|
extern void ARMul_SetPC (ARMul_State * state, ARMword value); |
||||
|
extern ARMword ARMul_GetR15 (ARMul_State * state); |
||||
|
extern void ARMul_SetR15 (ARMul_State * state, ARMword value); |
||||
|
|
||||
|
extern ARMword ARMul_GetCPSR (ARMul_State * state); |
||||
|
extern void ARMul_SetCPSR (ARMul_State * state, ARMword value); |
||||
|
extern ARMword ARMul_GetSPSR (ARMul_State * state, ARMword mode); |
||||
|
extern void ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value); |
||||
|
|
||||
|
/***************************************************************************\ |
||||
|
* Definitons of things to handle aborts * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
extern void ARMul_Abort (ARMul_State * state, ARMword address); |
||||
|
#ifdef MODET |
||||
|
#define ARMul_ABORTWORD (state->TFlag ? 0xefffdfff : 0xefffffff) /* SWI -1 */ |
||||
|
#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \ |
||||
|
state->AbortAddr = (address & (state->TFlag ? ~1L : ~3L)) |
||||
|
#else |
||||
|
#define ARMul_ABORTWORD 0xefffffff /* SWI -1 */ |
||||
|
#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \ |
||||
|
state->AbortAddr = (address & ~3L) |
||||
|
#endif |
||||
|
#define ARMul_DATAABORT(address) state->abortSig = HIGH ; \ |
||||
|
state->Aborted = ARMul_DataAbortV ; |
||||
|
#define ARMul_CLEARABORT state->abortSig = LOW |
||||
|
|
||||
|
/***************************************************************************\ |
||||
|
* Definitons of things in the memory interface * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
extern unsigned ARMul_MemoryInit (ARMul_State * state, |
||||
|
unsigned int initmemsize); |
||||
|
extern void ARMul_MemoryExit (ARMul_State * state); |
||||
|
|
||||
|
extern ARMword ARMul_LoadInstrS (ARMul_State * state, ARMword address, |
||||
|
ARMword isize); |
||||
|
extern ARMword ARMul_LoadInstrN (ARMul_State * state, ARMword address, |
||||
|
ARMword isize); |
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
extern ARMword ARMul_ReLoadInstr (ARMul_State * state, ARMword address, |
||||
|
ARMword isize); |
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
extern ARMword ARMul_LoadWordS (ARMul_State * state, ARMword address); |
||||
|
extern ARMword ARMul_LoadWordN (ARMul_State * state, ARMword address); |
||||
|
extern ARMword ARMul_LoadHalfWord (ARMul_State * state, ARMword address); |
||||
|
extern ARMword ARMul_LoadByte (ARMul_State * state, ARMword address); |
||||
|
|
||||
|
extern void ARMul_StoreWordS (ARMul_State * state, ARMword address, |
||||
|
ARMword data); |
||||
|
extern void ARMul_StoreWordN (ARMul_State * state, ARMword address, |
||||
|
ARMword data); |
||||
|
extern void ARMul_StoreHalfWord (ARMul_State * state, ARMword address, |
||||
|
ARMword data); |
||||
|
extern void ARMul_StoreByte (ARMul_State * state, ARMword address, |
||||
|
ARMword data); |
||||
|
|
||||
|
extern ARMword ARMul_SwapWord (ARMul_State * state, ARMword address, |
||||
|
ARMword data); |
||||
|
extern ARMword ARMul_SwapByte (ARMul_State * state, ARMword address, |
||||
|
ARMword data); |
||||
|
|
||||
|
extern void ARMul_Icycles (ARMul_State * state, unsigned number, |
||||
|
ARMword address); |
||||
|
extern void ARMul_Ccycles (ARMul_State * state, unsigned number, |
||||
|
ARMword address); |
||||
|
|
||||
|
extern ARMword ARMul_ReadWord (ARMul_State * state, ARMword address); |
||||
|
extern ARMword ARMul_ReadByte (ARMul_State * state, ARMword address); |
||||
|
extern void ARMul_WriteWord (ARMul_State * state, ARMword address, |
||||
|
ARMword data); |
||||
|
extern void ARMul_WriteByte (ARMul_State * state, ARMword address, |
||||
|
ARMword data); |
||||
|
|
||||
|
extern ARMword ARMul_MemAccess (ARMul_State * state, ARMword, ARMword, |
||||
|
ARMword, ARMword, ARMword, ARMword, ARMword, |
||||
|
ARMword, ARMword, ARMword); |
||||
|
|
||||
|
/***************************************************************************\ |
||||
|
* Definitons of things in the co-processor interface * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
#define ARMul_FIRST 0 |
||||
|
#define ARMul_TRANSFER 1 |
||||
|
#define ARMul_BUSY 2 |
||||
|
#define ARMul_DATA 3 |
||||
|
#define ARMul_INTERRUPT 4 |
||||
|
#define ARMul_DONE 0 |
||||
|
#define ARMul_CANT 1 |
||||
|
#define ARMul_INC 3 |
||||
|
|
||||
|
#define ARMul_CP13_R0_FIQ 0x1 |
||||
|
#define ARMul_CP13_R0_IRQ 0x2 |
||||
|
#define ARMul_CP13_R8_PMUS 0x1 |
||||
|
|
||||
|
#define ARMul_CP14_R0_ENABLE 0x0001 |
||||
|
#define ARMul_CP14_R0_CLKRST 0x0004 |
||||
|
#define ARMul_CP14_R0_CCD 0x0008 |
||||
|
#define ARMul_CP14_R0_INTEN0 0x0010 |
||||
|
#define ARMul_CP14_R0_INTEN1 0x0020 |
||||
|
#define ARMul_CP14_R0_INTEN2 0x0040 |
||||
|
#define ARMul_CP14_R0_FLAG0 0x0100 |
||||
|
#define ARMul_CP14_R0_FLAG1 0x0200 |
||||
|
#define ARMul_CP14_R0_FLAG2 0x0400 |
||||
|
#define ARMul_CP14_R10_MOE_IB 0x0004 |
||||
|
#define ARMul_CP14_R10_MOE_DB 0x0008 |
||||
|
#define ARMul_CP14_R10_MOE_BT 0x000c |
||||
|
#define ARMul_CP15_R1_ENDIAN 0x0080 |
||||
|
#define ARMul_CP15_R1_ALIGN 0x0002 |
||||
|
#define ARMul_CP15_R5_X 0x0400 |
||||
|
#define ARMul_CP15_R5_ST_ALIGN 0x0001 |
||||
|
#define ARMul_CP15_R5_IMPRE 0x0406 |
||||
|
#define ARMul_CP15_R5_MMU_EXCPT 0x0400 |
||||
|
#define ARMul_CP15_DBCON_M 0x0100 |
||||
|
#define ARMul_CP15_DBCON_E1 0x000c |
||||
|
#define ARMul_CP15_DBCON_E0 0x0003 |
||||
|
|
||||
|
extern unsigned ARMul_CoProInit (ARMul_State * state); |
||||
|
extern void ARMul_CoProExit (ARMul_State * state); |
||||
|
extern void ARMul_CoProAttach (ARMul_State * state, unsigned number, |
||||
|
ARMul_CPInits * init, ARMul_CPExits * exit, |
||||
|
ARMul_LDCs * ldc, ARMul_STCs * stc, |
||||
|
ARMul_MRCs * mrc, ARMul_MCRs * mcr, |
||||
|
ARMul_MRRCs * mrrc, ARMul_MCRRs * mcrr, |
||||
|
ARMul_CDPs * cdp, |
||||
|
ARMul_CPReads * read, ARMul_CPWrites * write); |
||||
|
extern void ARMul_CoProDetach (ARMul_State * state, unsigned number); |
||||
|
|
||||
|
/***************************************************************************\ |
||||
|
* Definitons of things in the host environment * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
extern unsigned ARMul_OSInit (ARMul_State * state); |
||||
|
extern void ARMul_OSExit (ARMul_State * state); |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
extern unsigned ARMul_OSHandleSWI (ARMul_State * state, ARMword number); |
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
|
||||
|
extern ARMword ARMul_OSLastErrorP (ARMul_State * state); |
||||
|
|
||||
|
extern ARMword ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr); |
||||
|
extern unsigned ARMul_OSException (ARMul_State * state, ARMword vector, |
||||
|
ARMword pc); |
||||
|
extern int rdi_log; |
||||
|
|
||||
|
/***************************************************************************\ |
||||
|
* Host-dependent stuff * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
#ifdef macintosh |
||||
|
pascal void SpinCursor (short increment); /* copied from CursorCtl.h */ |
||||
|
# define HOURGLASS SpinCursor( 1 ) |
||||
|
# define HOURGLASS_RATE 1023 /* 2^n - 1 */ |
||||
|
#endif |
||||
|
|
||||
|
//teawater add for arm2x86 2005.02.14------------------------------------------- |
||||
|
/*ywc 2005-03-31*/ |
||||
|
/* |
||||
|
#include "arm2x86.h" |
||||
|
#include "arm2x86_dp.h" |
||||
|
#include "arm2x86_movl.h" |
||||
|
#include "arm2x86_psr.h" |
||||
|
#include "arm2x86_shift.h" |
||||
|
#include "arm2x86_mem.h" |
||||
|
#include "arm2x86_mul.h" |
||||
|
#include "arm2x86_test.h" |
||||
|
#include "arm2x86_other.h" |
||||
|
#include "list.h" |
||||
|
#include "tb.h" |
||||
|
*/ |
||||
|
#define EQ 0 |
||||
|
#define NE 1 |
||||
|
#define CS 2 |
||||
|
#define CC 3 |
||||
|
#define MI 4 |
||||
|
#define PL 5 |
||||
|
#define VS 6 |
||||
|
#define VC 7 |
||||
|
#define HI 8 |
||||
|
#define LS 9 |
||||
|
#define GE 10 |
||||
|
#define LT 11 |
||||
|
#define GT 12 |
||||
|
#define LE 13 |
||||
|
#define AL 14 |
||||
|
#define NV 15 |
||||
|
|
||||
|
#ifndef NFLAG |
||||
|
#define NFLAG state->NFlag |
||||
|
#endif //NFLAG |
||||
|
|
||||
|
#ifndef ZFLAG |
||||
|
#define ZFLAG state->ZFlag |
||||
|
#endif //ZFLAG |
||||
|
|
||||
|
#ifndef CFLAG |
||||
|
#define CFLAG state->CFlag |
||||
|
#endif //CFLAG |
||||
|
|
||||
|
#ifndef VFLAG |
||||
|
#define VFLAG state->VFlag |
||||
|
#endif //VFLAG |
||||
|
|
||||
|
#ifndef IFLAG |
||||
|
#define IFLAG (state->IFFlags >> 1) |
||||
|
#endif //IFLAG |
||||
|
|
||||
|
#ifndef FFLAG |
||||
|
#define FFLAG (state->IFFlags & 1) |
||||
|
#endif //FFLAG |
||||
|
|
||||
|
#ifndef IFFLAGS |
||||
|
#define IFFLAGS state->IFFlags |
||||
|
#endif //VFLAG |
||||
|
|
||||
|
#define FLAG_MASK 0xf0000000 |
||||
|
#define NBIT_SHIFT 31 |
||||
|
#define ZBIT_SHIFT 30 |
||||
|
#define CBIT_SHIFT 29 |
||||
|
#define VBIT_SHIFT 28 |
||||
|
#ifdef DBCT |
||||
|
//teawater change for local tb branch directly jump 2005.10.18------------------ |
||||
|
#include "dbct/list.h" |
||||
|
#include "dbct/arm2x86.h" |
||||
|
#include "dbct/arm2x86_dp.h" |
||||
|
#include "dbct/arm2x86_movl.h" |
||||
|
#include "dbct/arm2x86_psr.h" |
||||
|
#include "dbct/arm2x86_shift.h" |
||||
|
#include "dbct/arm2x86_mem.h" |
||||
|
#include "dbct/arm2x86_mul.h" |
||||
|
#include "dbct/arm2x86_test.h" |
||||
|
#include "dbct/arm2x86_other.h" |
||||
|
#include "dbct/arm2x86_coproc.h" |
||||
|
#include "dbct/tb.h" |
||||
|
#endif |
||||
|
//AJ2D-------------------------------------------------------------------------- |
||||
|
//AJ2D-------------------------------------------------------------------------- |
||||
|
#define SKYEYE_OUTREGS(fd) { fprintf ((fd), "R %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,C %x,S %x,%x,%x,%x,%x,%x,%x,M %x,B %x,E %x,I %x,P %x,T %x,L %x,D %x,",\ |
||||
|
state->Reg[0],state->Reg[1],state->Reg[2],state->Reg[3], \ |
||||
|
state->Reg[4],state->Reg[5],state->Reg[6],state->Reg[7], \ |
||||
|
state->Reg[8],state->Reg[9],state->Reg[10],state->Reg[11], \ |
||||
|
state->Reg[12],state->Reg[13],state->Reg[14],state->Reg[15], \ |
||||
|
state->Cpsr, state->Spsr[0], state->Spsr[1], state->Spsr[2],\ |
||||
|
state->Spsr[3],state->Spsr[4], state->Spsr[5], state->Spsr[6],\ |
||||
|
state->Mode,state->Bank,state->ErrorCode,state->instr,state->pc,\ |
||||
|
state->temp,state->loaded,state->decoded);} |
||||
|
|
||||
|
#define SKYEYE_OUTMOREREGS(fd) { fprintf ((fd),"\ |
||||
|
RUs %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\ |
||||
|
RF %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\ |
||||
|
RI %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\ |
||||
|
RS %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\ |
||||
|
RA %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\ |
||||
|
RUn %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",\ |
||||
|
state->RegBank[0][0],state->RegBank[0][1],state->RegBank[0][2],state->RegBank[0][3], \ |
||||
|
state->RegBank[0][4],state->RegBank[0][5],state->RegBank[0][6],state->RegBank[0][7], \ |
||||
|
state->RegBank[0][8],state->RegBank[0][9],state->RegBank[0][10],state->RegBank[0][11], \ |
||||
|
state->RegBank[0][12],state->RegBank[0][13],state->RegBank[0][14],state->RegBank[0][15], \ |
||||
|
state->RegBank[1][0],state->RegBank[1][1],state->RegBank[1][2],state->RegBank[1][3], \ |
||||
|
state->RegBank[1][4],state->RegBank[1][5],state->RegBank[1][6],state->RegBank[1][7], \ |
||||
|
state->RegBank[1][8],state->RegBank[1][9],state->RegBank[1][10],state->RegBank[1][11], \ |
||||
|
state->RegBank[1][12],state->RegBank[1][13],state->RegBank[1][14],state->RegBank[1][15], \ |
||||
|
state->RegBank[2][0],state->RegBank[2][1],state->RegBank[2][2],state->RegBank[2][3], \ |
||||
|
state->RegBank[2][4],state->RegBank[2][5],state->RegBank[2][6],state->RegBank[2][7], \ |
||||
|
state->RegBank[2][8],state->RegBank[2][9],state->RegBank[2][10],state->RegBank[2][11], \ |
||||
|
state->RegBank[2][12],state->RegBank[2][13],state->RegBank[2][14],state->RegBank[2][15], \ |
||||
|
state->RegBank[3][0],state->RegBank[3][1],state->RegBank[3][2],state->RegBank[3][3], \ |
||||
|
state->RegBank[3][4],state->RegBank[3][5],state->RegBank[3][6],state->RegBank[3][7], \ |
||||
|
state->RegBank[3][8],state->RegBank[3][9],state->RegBank[3][10],state->RegBank[3][11], \ |
||||
|
state->RegBank[3][12],state->RegBank[3][13],state->RegBank[3][14],state->RegBank[3][15], \ |
||||
|
state->RegBank[4][0],state->RegBank[4][1],state->RegBank[4][2],state->RegBank[4][3], \ |
||||
|
state->RegBank[4][4],state->RegBank[4][5],state->RegBank[4][6],state->RegBank[4][7], \ |
||||
|
state->RegBank[4][8],state->RegBank[4][9],state->RegBank[4][10],state->RegBank[4][11], \ |
||||
|
state->RegBank[4][12],state->RegBank[4][13],state->RegBank[4][14],state->RegBank[4][15], \ |
||||
|
state->RegBank[5][0],state->RegBank[5][1],state->RegBank[5][2],state->RegBank[5][3], \ |
||||
|
state->RegBank[5][4],state->RegBank[5][5],state->RegBank[5][6],state->RegBank[5][7], \ |
||||
|
state->RegBank[5][8],state->RegBank[5][9],state->RegBank[5][10],state->RegBank[5][11], \ |
||||
|
state->RegBank[5][12],state->RegBank[5][13],state->RegBank[5][14],state->RegBank[5][15] \ |
||||
|
);} |
||||
|
|
||||
|
|
||||
|
#define SA1110 0x6901b110 |
||||
|
#define SA1100 0x4401a100 |
||||
|
#define PXA250 0x69052100 |
||||
|
#define PXA270 0x69054110 |
||||
|
//#define PXA250 0x69052903 |
||||
|
// 0x69052903; //PXA250 B1 from intel 278522-001.pdf |
||||
|
|
||||
|
|
||||
|
extern void ARMul_UndefInstr (ARMul_State *, ARMword); |
||||
|
extern void ARMul_FixCPSR (ARMul_State *, ARMword, ARMword); |
||||
|
extern void ARMul_FixSPSR (ARMul_State *, ARMword, ARMword); |
||||
|
extern void ARMul_ConsolePrint (ARMul_State *, const char *, ...); |
||||
|
extern void ARMul_SelectProcessor (ARMul_State *, unsigned); |
||||
|
|
||||
|
#define DIFF_LOG 0 |
||||
|
#define SAVE_LOG 0 |
||||
|
|
||||
|
#endif /* _ARMDEFS_H_ */ |
||||
6618
src/core/src/arm/armemu.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,657 @@ |
|||||
|
/* armemu.h -- ARMulator emulation macros: ARM6 Instruction Emulator. |
||||
|
Copyright (C) 1994 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. */ |
||||
|
#ifndef __ARMEMU_H__ |
||||
|
#define __ARMEMU_H__ |
||||
|
|
||||
|
#include "common.h" |
||||
|
#include "armdefs.h" |
||||
|
//#include "skyeye.h" |
||||
|
|
||||
|
extern ARMword isize; |
||||
|
|
||||
|
/* Condition code values. */ |
||||
|
#define EQ 0 |
||||
|
#define NE 1 |
||||
|
#define CS 2 |
||||
|
#define CC 3 |
||||
|
#define MI 4 |
||||
|
#define PL 5 |
||||
|
#define VS 6 |
||||
|
#define VC 7 |
||||
|
#define HI 8 |
||||
|
#define LS 9 |
||||
|
#define GE 10 |
||||
|
#define LT 11 |
||||
|
#define GT 12 |
||||
|
#define LE 13 |
||||
|
#define AL 14 |
||||
|
#define NV 15 |
||||
|
|
||||
|
/* Shift Opcodes. */ |
||||
|
#define LSL 0 |
||||
|
#define LSR 1 |
||||
|
#define ASR 2 |
||||
|
#define ROR 3 |
||||
|
|
||||
|
/* Macros to twiddle the status flags and mode. */ |
||||
|
#define NBIT ((unsigned)1L << 31) |
||||
|
#define ZBIT (1L << 30) |
||||
|
#define CBIT (1L << 29) |
||||
|
#define VBIT (1L << 28) |
||||
|
#define SBIT (1L << 27) |
||||
|
#define IBIT (1L << 7) |
||||
|
#define FBIT (1L << 6) |
||||
|
#define IFBITS (3L << 6) |
||||
|
#define R15IBIT (1L << 27) |
||||
|
#define R15FBIT (1L << 26) |
||||
|
#define R15IFBITS (3L << 26) |
||||
|
|
||||
|
#define POS(i) ( (~(i)) >> 31 ) |
||||
|
#define NEG(i) ( (i) >> 31 ) |
||||
|
|
||||
|
#ifdef MODET /* Thumb support. */ |
||||
|
/* ??? This bit is actually in the low order bit of the PC in the hardware. |
||||
|
It isn't clear if the simulator needs to model that or not. */ |
||||
|
#define TBIT (1L << 5) |
||||
|
#define TFLAG state->TFlag |
||||
|
#define SETT state->TFlag = 1 |
||||
|
#define CLEART state->TFlag = 0 |
||||
|
#define ASSIGNT(res) state->TFlag = res |
||||
|
#define INSN_SIZE (TFLAG ? 2 : 4) |
||||
|
#else |
||||
|
#define INSN_SIZE 4 |
||||
|
#define TFLAG 0 |
||||
|
#endif |
||||
|
|
||||
|
/*add armv6 CPSR feature*/ |
||||
|
#define EFLAG state->EFlag |
||||
|
#define SETE state->EFlag = 1 |
||||
|
#define CLEARE state->EFlag = 0 |
||||
|
#define ASSIGNE(res) state->NFlag = res |
||||
|
|
||||
|
#define AFLAG state->AFlag |
||||
|
#define SETA state->AFlag = 1 |
||||
|
#define CLEARA state->AFlag = 0 |
||||
|
#define ASSIGNA(res) state->NFlag = res |
||||
|
|
||||
|
#define QFLAG state->QFlag |
||||
|
#define SETQ state->QFlag = 1 |
||||
|
#define CLEARQ state->AFlag = 0 |
||||
|
#define ASSIGNQ(res) state->QFlag = res |
||||
|
|
||||
|
/* add end */ |
||||
|
|
||||
|
#define NFLAG state->NFlag |
||||
|
#define SETN state->NFlag = 1 |
||||
|
#define CLEARN state->NFlag = 0 |
||||
|
#define ASSIGNN(res) state->NFlag = res |
||||
|
|
||||
|
#define ZFLAG state->ZFlag |
||||
|
#define SETZ state->ZFlag = 1 |
||||
|
#define CLEARZ state->ZFlag = 0 |
||||
|
#define ASSIGNZ(res) state->ZFlag = res |
||||
|
|
||||
|
#define CFLAG state->CFlag |
||||
|
#define SETC state->CFlag = 1 |
||||
|
#define CLEARC state->CFlag = 0 |
||||
|
#define ASSIGNC(res) state->CFlag = res |
||||
|
|
||||
|
#define VFLAG state->VFlag |
||||
|
#define SETV state->VFlag = 1 |
||||
|
#define CLEARV state->VFlag = 0 |
||||
|
#define ASSIGNV(res) state->VFlag = res |
||||
|
|
||||
|
#define SFLAG state->SFlag |
||||
|
#define SETS state->SFlag = 1 |
||||
|
#define CLEARS state->SFlag = 0 |
||||
|
#define ASSIGNS(res) state->SFlag = res |
||||
|
|
||||
|
#define IFLAG (state->IFFlags >> 1) |
||||
|
#define FFLAG (state->IFFlags & 1) |
||||
|
#define IFFLAGS state->IFFlags |
||||
|
#define ASSIGNINT(res) state->IFFlags = (((res) >> 6) & 3) |
||||
|
#define ASSIGNR15INT(res) state->IFFlags = (((res) >> 26) & 3) ; |
||||
|
|
||||
|
#define PSR_FBITS (0xff000000L) |
||||
|
#define PSR_SBITS (0x00ff0000L) |
||||
|
#define PSR_XBITS (0x0000ff00L) |
||||
|
#define PSR_CBITS (0x000000ffL) |
||||
|
|
||||
|
#if defined MODE32 || defined MODET |
||||
|
#define CCBITS (0xf8000000L) |
||||
|
#else |
||||
|
#define CCBITS (0xf0000000L) |
||||
|
#endif |
||||
|
|
||||
|
#define INTBITS (0xc0L) |
||||
|
|
||||
|
#if defined MODET && defined MODE32 |
||||
|
#define PCBITS (0xffffffffL) |
||||
|
#else |
||||
|
#define PCBITS (0xfffffffcL) |
||||
|
#endif |
||||
|
|
||||
|
#define MODEBITS (0x1fL) |
||||
|
#define R15INTBITS (3L << 26) |
||||
|
|
||||
|
#if defined MODET && defined MODE32 |
||||
|
#define R15PCBITS (0x03ffffffL) |
||||
|
#else |
||||
|
#define R15PCBITS (0x03fffffcL) |
||||
|
#endif |
||||
|
|
||||
|
#define R15PCMODEBITS (0x03ffffffL) |
||||
|
#define R15MODEBITS (0x3L) |
||||
|
|
||||
|
#ifdef MODE32 |
||||
|
#define PCMASK PCBITS |
||||
|
#define PCWRAP(pc) (pc) |
||||
|
#else |
||||
|
#define PCMASK R15PCBITS |
||||
|
#define PCWRAP(pc) ((pc) & R15PCBITS) |
||||
|
#endif |
||||
|
|
||||
|
#define PC (state->Reg[15] & PCMASK) |
||||
|
#define R15CCINTMODE (state->Reg[15] & (CCBITS | R15INTBITS | R15MODEBITS)) |
||||
|
#define R15INT (state->Reg[15] & R15INTBITS) |
||||
|
#define R15INTPC (state->Reg[15] & (R15INTBITS | R15PCBITS)) |
||||
|
#define R15INTPCMODE (state->Reg[15] & (R15INTBITS | R15PCBITS | R15MODEBITS)) |
||||
|
#define R15INTMODE (state->Reg[15] & (R15INTBITS | R15MODEBITS)) |
||||
|
#define R15PC (state->Reg[15] & R15PCBITS) |
||||
|
#define R15PCMODE (state->Reg[15] & (R15PCBITS | R15MODEBITS)) |
||||
|
#define R15MODE (state->Reg[15] & R15MODEBITS) |
||||
|
|
||||
|
#define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28) | (SFLAG << 27)) |
||||
|
#define EINT (IFFLAGS << 6) |
||||
|
#define ER15INT (IFFLAGS << 26) |
||||
|
#define EMODE (state->Mode) |
||||
|
|
||||
|
#ifdef MODET |
||||
|
#define CPSR (ECC | EINT | EMODE | (TFLAG << 5)) |
||||
|
#else |
||||
|
#define CPSR (ECC | EINT | EMODE) |
||||
|
#endif |
||||
|
|
||||
|
#ifdef MODE32 |
||||
|
#define PATCHR15 |
||||
|
#else |
||||
|
#define PATCHR15 state->Reg[15] = ECC | ER15INT | EMODE | R15PC |
||||
|
#endif |
||||
|
|
||||
|
#define GETSPSR(bank) (ARMul_GetSPSR (state, EMODE)) |
||||
|
#define SETPSR_F(d,s) d = ((d) & ~PSR_FBITS) | ((s) & PSR_FBITS) |
||||
|
#define SETPSR_S(d,s) d = ((d) & ~PSR_SBITS) | ((s) & PSR_SBITS) |
||||
|
#define SETPSR_X(d,s) d = ((d) & ~PSR_XBITS) | ((s) & PSR_XBITS) |
||||
|
#define SETPSR_C(d,s) d = ((d) & ~PSR_CBITS) | ((s) & PSR_CBITS) |
||||
|
|
||||
|
#define SETR15PSR(s) \ |
||||
|
do \ |
||||
|
{ \ |
||||
|
if (state->Mode == USER26MODE) \ |
||||
|
{ \ |
||||
|
state->Reg[15] = ((s) & CCBITS) | R15PC | ER15INT | EMODE; \ |
||||
|
ASSIGNN ((state->Reg[15] & NBIT) != 0); \ |
||||
|
ASSIGNZ ((state->Reg[15] & ZBIT) != 0); \ |
||||
|
ASSIGNC ((state->Reg[15] & CBIT) != 0); \ |
||||
|
ASSIGNV ((state->Reg[15] & VBIT) != 0); \ |
||||
|
} \ |
||||
|
else \ |
||||
|
{ \ |
||||
|
state->Reg[15] = R15PC | ((s) & (CCBITS | R15INTBITS | R15MODEBITS)); \ |
||||
|
ARMul_R15Altered (state); \ |
||||
|
} \ |
||||
|
} \ |
||||
|
while (0) |
||||
|
|
||||
|
#define SETABORT(i, m, d) \ |
||||
|
do \ |
||||
|
{ \ |
||||
|
int SETABORT_mode = (m); \ |
||||
|
\ |
||||
|
ARMul_SetSPSR (state, SETABORT_mode, ARMul_GetCPSR (state)); \ |
||||
|
ARMul_SetCPSR (state, ((ARMul_GetCPSR (state) & ~(EMODE | TBIT)) \ |
||||
|
| (i) | SETABORT_mode)); \ |
||||
|
state->Reg[14] = temp - (d); \ |
||||
|
} \ |
||||
|
while (0) |
||||
|
|
||||
|
#ifndef MODE32 |
||||
|
#define VECTORS 0x20 |
||||
|
#define LEGALADDR 0x03ffffff |
||||
|
#define VECTORACCESS(address) (address < VECTORS && ARMul_MODE26BIT && state->prog32Sig) |
||||
|
#define ADDREXCEPT(address) (address > LEGALADDR && !state->data32Sig) |
||||
|
#endif |
||||
|
|
||||
|
#define INTERNALABORT(address) \ |
||||
|
do \ |
||||
|
{ \ |
||||
|
if (address < VECTORS) \ |
||||
|
state->Aborted = ARMul_DataAbortV; \ |
||||
|
else \ |
||||
|
state->Aborted = ARMul_AddrExceptnV; \ |
||||
|
} \ |
||||
|
while (0) |
||||
|
|
||||
|
#ifdef MODE32 |
||||
|
#define TAKEABORT ARMul_Abort (state, ARMul_DataAbortV) |
||||
|
#else |
||||
|
#define TAKEABORT \ |
||||
|
do \ |
||||
|
{ \ |
||||
|
if (state->Aborted == ARMul_AddrExceptnV) \ |
||||
|
ARMul_Abort (state, ARMul_AddrExceptnV); \ |
||||
|
else \ |
||||
|
ARMul_Abort (state, ARMul_DataAbortV); \ |
||||
|
} \ |
||||
|
while (0) |
||||
|
#endif |
||||
|
|
||||
|
#define CPTAKEABORT \ |
||||
|
do \ |
||||
|
{ \ |
||||
|
if (!state->Aborted) \ |
||||
|
ARMul_Abort (state, ARMul_UndefinedInstrV); \ |
||||
|
else if (state->Aborted == ARMul_AddrExceptnV) \ |
||||
|
ARMul_Abort (state, ARMul_AddrExceptnV); \ |
||||
|
else \ |
||||
|
ARMul_Abort (state, ARMul_DataAbortV); \ |
||||
|
} \ |
||||
|
while (0); |
||||
|
|
||||
|
|
||||
|
/* Different ways to start the next instruction. */ |
||||
|
#define SEQ 0 |
||||
|
#define NONSEQ 1 |
||||
|
#define PCINCEDSEQ 2 |
||||
|
#define PCINCEDNONSEQ 3 |
||||
|
#define PRIMEPIPE 4 |
||||
|
#define RESUME 8 |
||||
|
|
||||
|
/************************************/ |
||||
|
/* shenoubang 2012-3-11 */ |
||||
|
/* for armv7 DBG DMB DSB instr*/ |
||||
|
/************************************/ |
||||
|
#define MBReqTypes_Writes 0 |
||||
|
#define MBReqTypes_All 1 |
||||
|
|
||||
|
#define NORMALCYCLE state->NextInstr = 0 |
||||
|
#define BUSUSEDN state->NextInstr |= 1 /* The next fetch will be an N cycle. */ |
||||
|
#define BUSUSEDINCPCS \ |
||||
|
do \ |
||||
|
{ \ |
||||
|
if (! state->is_v4) \ |
||||
|
{ \ |
||||
|
/* A standard PC inc and an S cycle. */ \ |
||||
|
state->Reg[15] += isize; \ |
||||
|
state->NextInstr = (state->NextInstr & 0xff) | 2; \ |
||||
|
} \ |
||||
|
} \ |
||||
|
while (0) |
||||
|
|
||||
|
#define BUSUSEDINCPCN \ |
||||
|
do \ |
||||
|
{ \ |
||||
|
if (state->is_v4) \ |
||||
|
BUSUSEDN; \ |
||||
|
else \ |
||||
|
{ \ |
||||
|
/* A standard PC inc and an N cycle. */ \ |
||||
|
state->Reg[15] += isize; \ |
||||
|
state->NextInstr |= 3; \ |
||||
|
} \ |
||||
|
} \ |
||||
|
while (0) |
||||
|
|
||||
|
#define INCPC \ |
||||
|
do \ |
||||
|
{ \ |
||||
|
/* A standard PC inc. */ \ |
||||
|
state->Reg[15] += isize; \ |
||||
|
state->NextInstr |= 2; \ |
||||
|
} \ |
||||
|
while (0) |
||||
|
|
||||
|
#define FLUSHPIPE state->NextInstr |= PRIMEPIPE |
||||
|
|
||||
|
/* Cycle based emulation. */ |
||||
|
|
||||
|
#define OUTPUTCP(i,a,b) |
||||
|
#define NCYCLE |
||||
|
#define SCYCLE |
||||
|
#define ICYCLE |
||||
|
#define CCYCLE |
||||
|
#define NEXTCYCLE(c) |
||||
|
|
||||
|
/* Macros to extract parts of instructions. */ |
||||
|
#define DESTReg (BITS (12, 15)) |
||||
|
#define LHSReg (BITS (16, 19)) |
||||
|
#define RHSReg (BITS ( 0, 3)) |
||||
|
|
||||
|
#define DEST (state->Reg[DESTReg]) |
||||
|
|
||||
|
#ifdef MODE32 |
||||
|
#ifdef MODET |
||||
|
#define LHS ((LHSReg == 15) ? (state->Reg[15] & 0xFFFFFFFC) : (state->Reg[LHSReg])) |
||||
|
#define RHS ((RHSReg == 15) ? (state->Reg[15] & 0xFFFFFFFC) : (state->Reg[RHSReg])) |
||||
|
#else |
||||
|
#define LHS (state->Reg[LHSReg]) |
||||
|
#define RHS (state->Reg[RHSReg]) |
||||
|
#endif |
||||
|
#else |
||||
|
#define LHS ((LHSReg == 15) ? R15PC : (state->Reg[LHSReg])) |
||||
|
#define RHS ((RHSReg == 15) ? R15PC : (state->Reg[RHSReg])) |
||||
|
#endif |
||||
|
|
||||
|
#define MULDESTReg (BITS (16, 19)) |
||||
|
#define MULLHSReg (BITS ( 0, 3)) |
||||
|
#define MULRHSReg (BITS ( 8, 11)) |
||||
|
#define MULACCReg (BITS (12, 15)) |
||||
|
|
||||
|
#define DPImmRHS (ARMul_ImmedTable[BITS(0, 11)]) |
||||
|
#define DPSImmRHS temp = BITS(0,11) ; \ |
||||
|
rhs = ARMul_ImmedTable[temp] ; \ |
||||
|
if (temp > 255) /* There was a shift. */ \ |
||||
|
ASSIGNC (rhs >> 31) ; |
||||
|
|
||||
|
#ifdef MODE32 |
||||
|
#define DPRegRHS ((BITS (4,11) == 0) ? state->Reg[RHSReg] \ |
||||
|
: GetDPRegRHS (state, instr)) |
||||
|
#define DPSRegRHS ((BITS (4,11) == 0) ? state->Reg[RHSReg] \ |
||||
|
: GetDPSRegRHS (state, instr)) |
||||
|
#else |
||||
|
#define DPRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \ |
||||
|
: GetDPRegRHS (state, instr)) |
||||
|
#define DPSRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \ |
||||
|
: GetDPSRegRHS (state, instr)) |
||||
|
#endif |
||||
|
|
||||
|
#define LSBase state->Reg[LHSReg] |
||||
|
#define LSImmRHS (BITS(0,11)) |
||||
|
|
||||
|
#ifdef MODE32 |
||||
|
#define LSRegRHS ((BITS (4, 11) == 0) ? state->Reg[RHSReg] \ |
||||
|
: GetLSRegRHS (state, instr)) |
||||
|
#else |
||||
|
#define LSRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \ |
||||
|
: GetLSRegRHS (state, instr)) |
||||
|
#endif |
||||
|
|
||||
|
#define LSMNumRegs ((ARMword) ARMul_BitList[BITS (0, 7)] + \ |
||||
|
(ARMword) ARMul_BitList[BITS (8, 15)] ) |
||||
|
#define LSMBaseFirst ((LHSReg == 0 && BIT (0)) || \ |
||||
|
(BIT (LHSReg) && BITS (0, LHSReg - 1) == 0)) |
||||
|
|
||||
|
#define SWAPSRC (state->Reg[RHSReg]) |
||||
|
|
||||
|
#define LSCOff (BITS (0, 7) << 2) |
||||
|
#define CPNum BITS (8, 11) |
||||
|
|
||||
|
/* Determine if access to coprocessor CP is permitted. |
||||
|
The XScale has a register in CP15 which controls access to CP0 - CP13. */ |
||||
|
//chy 2003-09-03, new CP_ACCESS_ALLOWED |
||||
|
/* |
||||
|
#define CP_ACCESS_ALLOWED(STATE, CP) \ |
||||
|
( ((CP) >= 14) \ |
||||
|
|| (! (STATE)->is_XScale) \ |
||||
|
|| (read_cp15_reg (15, 0, 1) & (1 << (CP)))) |
||||
|
*/ |
||||
|
#define CP_ACCESS_ALLOWED(STATE, CP) \ |
||||
|
( ((CP) >= 14) \ |
||||
|
|| (! (STATE)->is_XScale) \ |
||||
|
|| (xscale_cp15_cp_access_allowed(STATE,15,CP))) |
||||
|
|
||||
|
/* Macro to rotate n right by b bits. */ |
||||
|
#define ROTATER(n, b) (((n) >> (b)) | ((n) << (32 - (b)))) |
||||
|
|
||||
|
/* Macros to store results of instructions. */ |
||||
|
#define WRITEDEST(d) \ |
||||
|
do \ |
||||
|
{ \ |
||||
|
if (DESTReg == 15) \ |
||||
|
WriteR15 (state, d); \ |
||||
|
else \ |
||||
|
DEST = d; \ |
||||
|
} \ |
||||
|
while (0) |
||||
|
|
||||
|
#define WRITESDEST(d) \ |
||||
|
do \ |
||||
|
{ \ |
||||
|
if (DESTReg == 15) \ |
||||
|
WriteSR15 (state, d); \ |
||||
|
else \ |
||||
|
{ \ |
||||
|
DEST = d; \ |
||||
|
ARMul_NegZero (state, d); \ |
||||
|
} \ |
||||
|
} \ |
||||
|
while (0) |
||||
|
|
||||
|
#define WRITEDESTB(d) \ |
||||
|
do \ |
||||
|
{ \ |
||||
|
if (DESTReg == 15){ \ |
||||
|
WriteR15Branch (state, d); \ |
||||
|
} \ |
||||
|
else{ \ |
||||
|
DEST = d; \ |
||||
|
} \ |
||||
|
} \ |
||||
|
while (0) |
||||
|
|
||||
|
#define BYTETOBUS(data) ((data & 0xff) | \ |
||||
|
((data & 0xff) << 8) | \ |
||||
|
((data & 0xff) << 16) | \ |
||||
|
((data & 0xff) << 24)) |
||||
|
|
||||
|
#define BUSTOBYTE(address, data) \ |
||||
|
do \ |
||||
|
{ \ |
||||
|
if (state->bigendSig) \ |
||||
|
temp = (data >> (((address ^ 3) & 3) << 3)) & 0xff; \ |
||||
|
else \ |
||||
|
temp = (data >> ((address & 3) << 3)) & 0xff; \ |
||||
|
} \ |
||||
|
while (0) |
||||
|
|
||||
|
#define LOADMULT(instr, address, wb) LoadMult (state, instr, address, wb) |
||||
|
#define LOADSMULT(instr, address, wb) LoadSMult (state, instr, address, wb) |
||||
|
#define STOREMULT(instr, address, wb) StoreMult (state, instr, address, wb) |
||||
|
#define STORESMULT(instr, address, wb) StoreSMult (state, instr, address, wb) |
||||
|
|
||||
|
#define POSBRANCH ((instr & 0x7fffff) << 2) |
||||
|
#define NEGBRANCH ((0xff000000 |(instr & 0xffffff)) << 2) |
||||
|
|
||||
|
|
||||
|
/* Values for Emulate. */ |
||||
|
#define STOP 0 /* stop */ |
||||
|
#define CHANGEMODE 1 /* change mode */ |
||||
|
#define ONCE 2 /* execute just one interation */ |
||||
|
#define RUN 3 /* continuous execution */ |
||||
|
|
||||
|
/* Stuff that is shared across modes. */ |
||||
|
extern unsigned ARMul_MultTable[]; /* Number of I cycles for a mult. */ |
||||
|
extern ARMword ARMul_ImmedTable[]; /* Immediate DP LHS values. */ |
||||
|
extern char ARMul_BitList[]; /* Number of bits in a byte table. */ |
||||
|
|
||||
|
#define EVENTLISTSIZE 1024L |
||||
|
|
||||
|
/* Thumb support. */ |
||||
|
typedef enum |
||||
|
{ |
||||
|
t_undefined, /* Undefined Thumb instruction. */ |
||||
|
t_decoded, /* Instruction decoded to ARM equivalent. */ |
||||
|
t_branch /* Thumb branch (already processed). */ |
||||
|
} |
||||
|
tdstate; |
||||
|
|
||||
|
/********************************************************************************* |
||||
|
* Check all the possible undef or unpredict behavior, Some of them probably is |
||||
|
* out-of-updated with the newer ISA. |
||||
|
* -- Michael.Kang |
||||
|
********************************************************************************/ |
||||
|
#define UNDEF_WARNING ERROR_LOG(ARM11, "undefined or unpredicted behavior for arm instruction.\n"); |
||||
|
|
||||
|
/* Macros to scrutinize instructions. */ |
||||
|
#define UNDEF_Test UNDEF_WARNING |
||||
|
//#define UNDEF_Test |
||||
|
|
||||
|
//#define UNDEF_Shift UNDEF_WARNING |
||||
|
#define UNDEF_Shift |
||||
|
|
||||
|
//#define UNDEF_MSRPC UNDEF_WARNING |
||||
|
#define UNDEF_MSRPC |
||||
|
|
||||
|
//#define UNDEF_MRSPC UNDEF_WARNING |
||||
|
#define UNDEF_MRSPC |
||||
|
|
||||
|
#define UNDEF_MULPCDest UNDEF_WARNING |
||||
|
//#define UNDEF_MULPCDest |
||||
|
|
||||
|
#define UNDEF_MULDestEQOp1 UNDEF_WARNING |
||||
|
//#define UNDEF_MULDestEQOp1 |
||||
|
|
||||
|
//#define UNDEF_LSRBPC UNDEF_WARNING |
||||
|
#define UNDEF_LSRBPC |
||||
|
|
||||
|
//#define UNDEF_LSRBaseEQOffWb UNDEF_WARNING |
||||
|
#define UNDEF_LSRBaseEQOffWb |
||||
|
|
||||
|
//#define UNDEF_LSRBaseEQDestWb UNDEF_WARNING |
||||
|
#define UNDEF_LSRBaseEQDestWb |
||||
|
|
||||
|
//#define UNDEF_LSRPCBaseWb UNDEF_WARNING |
||||
|
#define UNDEF_LSRPCBaseWb |
||||
|
|
||||
|
//#define UNDEF_LSRPCOffWb UNDEF_WARNING |
||||
|
#define UNDEF_LSRPCOffWb |
||||
|
|
||||
|
//#define UNDEF_LSMNoRegs UNDEF_WARNING |
||||
|
#define UNDEF_LSMNoRegs |
||||
|
|
||||
|
//#define UNDEF_LSMPCBase UNDEF_WARNING |
||||
|
#define UNDEF_LSMPCBase |
||||
|
|
||||
|
//#define UNDEF_LSMUserBankWb UNDEF_WARNING |
||||
|
#define UNDEF_LSMUserBankWb |
||||
|
|
||||
|
//#define UNDEF_LSMBaseInListWb UNDEF_WARNING |
||||
|
#define UNDEF_LSMBaseInListWb |
||||
|
|
||||
|
#define UNDEF_SWPPC UNDEF_WARNING |
||||
|
//#define UNDEF_SWPPC |
||||
|
|
||||
|
#define UNDEF_CoProHS UNDEF_WARNING |
||||
|
//#define UNDEF_CoProHS |
||||
|
|
||||
|
#define UNDEF_MCRPC UNDEF_WARNING |
||||
|
//#define UNDEF_MCRPC |
||||
|
|
||||
|
//#define UNDEF_LSCPCBaseWb UNDEF_WARNING |
||||
|
#define UNDEF_LSCPCBaseWb |
||||
|
|
||||
|
#define UNDEF_UndefNotBounced UNDEF_WARNING |
||||
|
//#define UNDEF_UndefNotBounced |
||||
|
|
||||
|
#define UNDEF_ShortInt UNDEF_WARNING |
||||
|
//#define UNDEF_ShortInt |
||||
|
|
||||
|
#define UNDEF_IllegalMode UNDEF_WARNING |
||||
|
//#define UNDEF_IllegalMode |
||||
|
|
||||
|
#define UNDEF_Prog32SigChange UNDEF_WARNING |
||||
|
//#define UNDEF_Prog32SigChange |
||||
|
|
||||
|
#define UNDEF_Data32SigChange UNDEF_WARNING |
||||
|
//#define UNDEF_Data32SigChange |
||||
|
|
||||
|
/* Prototypes for exported functions. */ |
||||
|
extern unsigned ARMul_NthReg (ARMword, unsigned); |
||||
|
extern int AddOverflow (ARMword, ARMword, ARMword); |
||||
|
extern int SubOverflow (ARMword, ARMword, ARMword); |
||||
|
/* Prototypes for exported functions. */ |
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
extern ARMword ARMul_Emulate26 (ARMul_State *); |
||||
|
extern ARMword ARMul_Emulate32 (ARMul_State *); |
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
extern unsigned IntPending (ARMul_State *); |
||||
|
extern void ARMul_CPSRAltered (ARMul_State *); |
||||
|
extern void ARMul_R15Altered (ARMul_State *); |
||||
|
extern ARMword ARMul_GetPC (ARMul_State *); |
||||
|
extern ARMword ARMul_GetNextPC (ARMul_State *); |
||||
|
extern ARMword ARMul_GetR15 (ARMul_State *); |
||||
|
extern ARMword ARMul_GetCPSR (ARMul_State *); |
||||
|
extern void ARMul_EnvokeEvent (ARMul_State *); |
||||
|
extern unsigned int ARMul_Time (ARMul_State *); |
||||
|
extern void ARMul_NegZero (ARMul_State *, ARMword); |
||||
|
extern void ARMul_SetPC (ARMul_State *, ARMword); |
||||
|
extern void ARMul_SetR15 (ARMul_State *, ARMword); |
||||
|
extern void ARMul_SetCPSR (ARMul_State *, ARMword); |
||||
|
extern ARMword ARMul_GetSPSR (ARMul_State *, ARMword); |
||||
|
extern void ARMul_Abort26 (ARMul_State *, ARMword); |
||||
|
extern void ARMul_Abort32 (ARMul_State *, ARMword); |
||||
|
extern ARMword ARMul_MRC (ARMul_State *, ARMword); |
||||
|
extern void ARMul_MRRC (ARMul_State *, ARMword, ARMword *, ARMword *); |
||||
|
extern void ARMul_CDP (ARMul_State *, ARMword); |
||||
|
extern void ARMul_LDC (ARMul_State *, ARMword, ARMword); |
||||
|
extern void ARMul_STC (ARMul_State *, ARMword, ARMword); |
||||
|
extern void ARMul_MCR (ARMul_State *, ARMword, ARMword); |
||||
|
extern void ARMul_MCRR (ARMul_State *, ARMword, ARMword, ARMword); |
||||
|
extern void ARMul_SetSPSR (ARMul_State *, ARMword, ARMword); |
||||
|
extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword); |
||||
|
extern ARMword ARMul_Align (ARMul_State *, ARMword, ARMword); |
||||
|
extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword); |
||||
|
extern void ARMul_MSRCpsr (ARMul_State *, ARMword, ARMword); |
||||
|
extern void ARMul_SubOverflow (ARMul_State *, ARMword, ARMword, ARMword); |
||||
|
extern void ARMul_AddOverflow (ARMul_State *, ARMword, ARMword, ARMword); |
||||
|
extern void ARMul_SubCarry (ARMul_State *, ARMword, ARMword, ARMword); |
||||
|
extern void ARMul_AddCarry (ARMul_State *, ARMword, ARMword, ARMword); |
||||
|
extern tdstate ARMul_ThumbDecode (ARMul_State *, ARMword, ARMword, ARMword *); |
||||
|
extern ARMword ARMul_GetReg (ARMul_State *, unsigned, unsigned); |
||||
|
extern void ARMul_SetReg (ARMul_State *, unsigned, unsigned, ARMword); |
||||
|
extern void ARMul_ScheduleEvent (ARMul_State *, unsigned int, |
||||
|
unsigned (*)(ARMul_State *)); |
||||
|
/* Coprocessor support functions. */ |
||||
|
extern unsigned ARMul_CoProInit (ARMul_State *); |
||||
|
extern void ARMul_CoProExit (ARMul_State *); |
||||
|
extern void ARMul_CoProAttach (ARMul_State *, unsigned, ARMul_CPInits *, |
||||
|
ARMul_CPExits *, ARMul_LDCs *, ARMul_STCs *, |
||||
|
ARMul_MRCs *, ARMul_MCRs *, ARMul_MRRCs *, ARMul_MCRRs *, |
||||
|
ARMul_CDPs *, ARMul_CPReads *, ARMul_CPWrites *); |
||||
|
extern void ARMul_CoProDetach (ARMul_State *, unsigned); |
||||
|
extern ARMword read_cp15_reg (unsigned, unsigned, unsigned); |
||||
|
|
||||
|
extern unsigned DSPLDC4 (ARMul_State *, unsigned, ARMword, ARMword); |
||||
|
extern unsigned DSPMCR4 (ARMul_State *, unsigned, ARMword, ARMword); |
||||
|
extern unsigned DSPMRC4 (ARMul_State *, unsigned, ARMword, ARMword *); |
||||
|
extern unsigned DSPSTC4 (ARMul_State *, unsigned, ARMword, ARMword *); |
||||
|
extern unsigned DSPCDP4 (ARMul_State *, unsigned, ARMword); |
||||
|
extern unsigned DSPMCR5 (ARMul_State *, unsigned, ARMword, ARMword); |
||||
|
extern unsigned DSPMRC5 (ARMul_State *, unsigned, ARMword, ARMword *); |
||||
|
extern unsigned DSPLDC5 (ARMul_State *, unsigned, ARMword, ARMword); |
||||
|
extern unsigned DSPSTC5 (ARMul_State *, unsigned, ARMword, ARMword *); |
||||
|
extern unsigned DSPCDP5 (ARMul_State *, unsigned, ARMword); |
||||
|
extern unsigned DSPMCR6 (ARMul_State *, unsigned, ARMword, ARMword); |
||||
|
extern unsigned DSPMRC6 (ARMul_State *, unsigned, ARMword, ARMword *); |
||||
|
extern unsigned DSPCDP6 (ARMul_State *, unsigned, ARMword); |
||||
|
|
||||
|
|
||||
|
#endif |
||||
@ -0,0 +1,578 @@ |
|||||
|
/* arminit.c -- ARMulator initialization: ARM6 Instruction Emulator.
|
||||
|
Copyright (C) 1994 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 "platform.h"
|
||||
|
#if EMU_PLATFORM == PLATFORM_LINUX
|
||||
|
#include <unistd.h>
|
||||
|
#endif
|
||||
|
|
||||
|
#include <math.h>
|
||||
|
|
||||
|
#include "armdefs.h"
|
||||
|
#include "armemu.h"
|
||||
|
|
||||
|
/***************************************************************************\
|
||||
|
* Definitions for the emulator architecture * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
void ARMul_EmulateInit (void); |
||||
|
ARMul_State *ARMul_NewState (ARMul_State * state); |
||||
|
void ARMul_Reset (ARMul_State * state); |
||||
|
ARMword ARMul_DoCycle (ARMul_State * state); |
||||
|
unsigned ARMul_DoCoPro (ARMul_State * state); |
||||
|
ARMword ARMul_DoProg (ARMul_State * state); |
||||
|
ARMword ARMul_DoInstr (ARMul_State * state); |
||||
|
void ARMul_Abort (ARMul_State * state, ARMword address); |
||||
|
|
||||
|
unsigned ARMul_MultTable[32] = |
||||
|
{ 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, |
||||
|
10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16 |
||||
|
}; |
||||
|
ARMword ARMul_ImmedTable[4096]; /* immediate DP LHS values */ |
||||
|
char ARMul_BitList[256]; /* number of bits in a byte table */ |
||||
|
|
||||
|
//chy 2006-02-22 add test debugmode
|
||||
|
extern int debugmode; |
||||
|
extern int remote_interrupt( void ); |
||||
|
|
||||
|
|
||||
|
void arm_dyncom_Abort(ARMul_State * state, ARMword vector) |
||||
|
{ |
||||
|
ARMul_Abort(state, vector); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/* ahe-ykl : the following code to initialize user mode
|
||||
|
code is architecture dependent and probably model dependant. */ |
||||
|
|
||||
|
//#include "skyeye_arch.h"
|
||||
|
//#include "skyeye_pref.h"
|
||||
|
//#include "skyeye_exec_info.h"
|
||||
|
//#include "bank_defs.h"
|
||||
|
#include "armcpu.h"
|
||||
|
//#include "skyeye_callback.h"
|
||||
|
|
||||
|
//void arm_user_mode_init(generic_arch_t * arch_instance)
|
||||
|
//{
|
||||
|
// sky_pref_t *pref = get_skyeye_pref();
|
||||
|
//
|
||||
|
// if (pref->user_mode_sim)
|
||||
|
// {
|
||||
|
// sky_exec_info_t *info = get_skyeye_exec_info();
|
||||
|
// info->arch_page_size = 0x1000;
|
||||
|
// info->arch_stack_top = 0x1ffffff0;// + 0x401fe7 - 0xff0; /* arbitrary value */
|
||||
|
// /* stack initial address specific to architecture may be placed here */
|
||||
|
//
|
||||
|
// /* we need to mmap the stack space, if we are using skyeye space */
|
||||
|
// if (info->mmap_access)
|
||||
|
// {
|
||||
|
// /* get system stack size */
|
||||
|
// size_t stacksize = 0;
|
||||
|
// pthread_attr_t attr;
|
||||
|
// pthread_attr_init(&attr);
|
||||
|
// pthread_attr_getstacksize(&attr, &stacksize);
|
||||
|
// if (stacksize > info->arch_stack_top)
|
||||
|
// {
|
||||
|
// printf("arch_stack_top is too low\n");
|
||||
|
// stacksize = info->arch_stack_top;
|
||||
|
// }
|
||||
|
//
|
||||
|
// /* Note: Skyeye is occupating 0x400000 to 0x600000 */
|
||||
|
// /* We do a mmap */
|
||||
|
// void* ret = mmap( (info->arch_stack_top) - stacksize,
|
||||
|
// stacksize + 0x1000 , PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||
|
// if (ret == MAP_FAILED){
|
||||
|
// /* ideally, we should find an empty space until it works */
|
||||
|
// printf("mmap error, stack couldn't be mapped: errno %d\n", errno);
|
||||
|
// exit(-1);
|
||||
|
// } else {
|
||||
|
// memset(ret, '\0', stacksize);
|
||||
|
// //printf("stack top has been defined at %x size %x\n", (uint32_t) ret + stacksize, stacksize);
|
||||
|
// //info->arch_stack_top = (uint32_t) ret + stacksize;
|
||||
|
// }
|
||||
|
// }
|
||||
|
//
|
||||
|
// exec_stack_init();
|
||||
|
//
|
||||
|
// ARM_CPU_State* cpu = get_current_cpu();
|
||||
|
// arm_core_t* core = &cpu->core[0];
|
||||
|
//
|
||||
|
// uint32_t sp = info->initial_sp;
|
||||
|
//
|
||||
|
// core->Cpsr = 0x10; /* User mode */
|
||||
|
// /* FIXME: may need to add thumb */
|
||||
|
// core->Reg[13] = sp;
|
||||
|
// core->Reg[10] = info->start_data;
|
||||
|
// core->Reg[0] = 0;
|
||||
|
// bus_read(32, sp + 4, &(core->Reg[1]));
|
||||
|
// bus_read(32, sp + 8, &(core->Reg[2]));
|
||||
|
// }
|
||||
|
//
|
||||
|
//}
|
||||
|
|
||||
|
/***************************************************************************\
|
||||
|
* Call this routine once to set up the emulator's tables. * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
void |
||||
|
ARMul_EmulateInit (void) |
||||
|
{ |
||||
|
unsigned int i, j; |
||||
|
|
||||
|
for (i = 0; i < 4096; i++) { /* the values of 12 bit dp rhs's */ |
||||
|
ARMul_ImmedTable[i] = ROTATER (i & 0xffL, (i >> 7L) & 0x1eL); |
||||
|
} |
||||
|
|
||||
|
for (i = 0; i < 256; ARMul_BitList[i++] = 0); /* how many bits in LSM */ |
||||
|
for (j = 1; j < 256; j <<= 1) |
||||
|
for (i = 0; i < 256; i++) |
||||
|
if ((i & j) > 0) |
||||
|
ARMul_BitList[i]++; |
||||
|
|
||||
|
for (i = 0; i < 256; i++) |
||||
|
ARMul_BitList[i] *= 4; /* you always need 4 times these values */ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/***************************************************************************\
|
||||
|
* Returns a new instantiation of the ARMulator's state * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
ARMul_State * |
||||
|
ARMul_NewState (ARMul_State *state) |
||||
|
{ |
||||
|
unsigned i, j; |
||||
|
|
||||
|
memset (state, 0, sizeof (ARMul_State)); |
||||
|
|
||||
|
state->Emulate = RUN; |
||||
|
for (i = 0; i < 16; i++) { |
||||
|
state->Reg[i] = 0; |
||||
|
for (j = 0; j < 7; j++) |
||||
|
state->RegBank[j][i] = 0; |
||||
|
} |
||||
|
for (i = 0; i < 7; i++) |
||||
|
state->Spsr[i] = 0; |
||||
|
state->Mode = 0; |
||||
|
|
||||
|
state->CallDebug = FALSE; |
||||
|
state->Debug = FALSE; |
||||
|
state->VectorCatch = 0; |
||||
|
state->Aborted = FALSE; |
||||
|
state->Reseted = FALSE; |
||||
|
state->Inted = 3; |
||||
|
state->LastInted = 3; |
||||
|
|
||||
|
state->CommandLine = NULL; |
||||
|
|
||||
|
state->EventSet = 0; |
||||
|
state->Now = 0; |
||||
|
state->EventPtr = |
||||
|
(struct EventNode **) malloc ((unsigned) EVENTLISTSIZE * |
||||
|
sizeof (struct EventNode *)); |
||||
|
#if DIFF_STATE
|
||||
|
state->state_log = fopen("/data/state.log", "w"); |
||||
|
printf("create pc log file.\n"); |
||||
|
#endif
|
||||
|
if (state->EventPtr == NULL) { |
||||
|
printf ("SKYEYE: ARMul_NewState malloc state->EventPtr error\n"); |
||||
|
exit(-1); |
||||
|
} |
||||
|
for (i = 0; i < EVENTLISTSIZE; i++) |
||||
|
*(state->EventPtr + i) = NULL; |
||||
|
#if SAVE_LOG
|
||||
|
state->state_log = fopen("/tmp/state.log", "w"); |
||||
|
printf("create pc log file.\n"); |
||||
|
#else
|
||||
|
#if DIFF_LOG
|
||||
|
state->state_log = fopen("/tmp/state.log", "r"); |
||||
|
printf("loaded pc log file.\n"); |
||||
|
#endif
|
||||
|
#endif
|
||||
|
|
||||
|
#ifdef ARM61
|
||||
|
state->prog32Sig = LOW; |
||||
|
state->data32Sig = LOW; |
||||
|
#else
|
||||
|
state->prog32Sig = HIGH; |
||||
|
state->data32Sig = HIGH; |
||||
|
#endif
|
||||
|
|
||||
|
state->lateabtSig = HIGH; |
||||
|
state->bigendSig = LOW; |
||||
|
|
||||
|
//chy:2003-08-19
|
||||
|
state->LastTime = 0; |
||||
|
state->CP14R0_CCD = -1; |
||||
|
|
||||
|
/* ahe-ykl: common function for interpret and dyncom */ |
||||
|
//sky_pref_t *pref = get_skyeye_pref();
|
||||
|
//if (pref->user_mode_sim)
|
||||
|
// register_callback(arm_user_mode_init, Bootmach_callback);
|
||||
|
|
||||
|
memset(&state->exclusive_tag_array[0], 0xFF, sizeof(state->exclusive_tag_array[0]) * 128); |
||||
|
state->exclusive_access_state = 0; |
||||
|
//state->cpu = (cpu_config_t *) malloc (sizeof (cpu_config_t));
|
||||
|
//state->mem_bank = (mem_config_t *) malloc (sizeof (mem_config_t));
|
||||
|
return (state); |
||||
|
} |
||||
|
|
||||
|
/***************************************************************************\
|
||||
|
* Call this routine to set ARMulator to model a certain processor * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
void |
||||
|
ARMul_SelectProcessor (ARMul_State * state, unsigned properties) |
||||
|
{ |
||||
|
if (properties & ARM_Fix26_Prop) { |
||||
|
state->prog32Sig = LOW; |
||||
|
state->data32Sig = LOW; |
||||
|
} |
||||
|
else { |
||||
|
state->prog32Sig = HIGH; |
||||
|
state->data32Sig = HIGH; |
||||
|
} |
||||
|
/* 2004-05-09 chy
|
||||
|
below line sould be in skyeye_mach_XXX.c 's XXX_mach_init function |
||||
|
*/ |
||||
|
// state->lateabtSig = HIGH;
|
||||
|
|
||||
|
|
||||
|
state->is_v4 = |
||||
|
(properties & (ARM_v4_Prop | ARM_v5_Prop)) ? HIGH : LOW; |
||||
|
state->is_v5 = (properties & ARM_v5_Prop) ? HIGH : LOW; |
||||
|
state->is_v5e = (properties & ARM_v5e_Prop) ? HIGH : LOW; |
||||
|
state->is_XScale = (properties & ARM_XScale_Prop) ? HIGH : LOW; |
||||
|
state->is_iWMMXt = (properties & ARM_iWMMXt_Prop) ? HIGH : LOW; |
||||
|
/* state->is_v6 = LOW */; |
||||
|
/* jeff.du 2010-08-05 */ |
||||
|
state->is_v6 = (properties & ARM_v6_Prop) ? HIGH : LOW; |
||||
|
state->is_ep9312 = (properties & ARM_ep9312_Prop) ? HIGH : LOW; |
||||
|
//chy 2005-09-19
|
||||
|
state->is_pxa27x = (properties & ARM_PXA27X_Prop) ? HIGH : LOW; |
||||
|
|
||||
|
/* shenoubang 2012-3-11 */ |
||||
|
state->is_v7 = (properties & ARM_v7_Prop) ? HIGH : LOW; |
||||
|
|
||||
|
/* Only initialse the coprocessor support once we
|
||||
|
know what kind of chip we are dealing with. */ |
||||
|
ARMul_CoProInit (state); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/***************************************************************************\
|
||||
|
* Call this routine to set up the initial machine state (or perform a RESET * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
void |
||||
|
ARMul_Reset (ARMul_State * state) |
||||
|
{ |
||||
|
//fprintf(stderr,"armul_reset 0: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);
|
||||
|
state->NextInstr = 0; |
||||
|
if (state->prog32Sig) { |
||||
|
state->Reg[15] = 0; |
||||
|
state->Cpsr = INTBITS | SVC32MODE; |
||||
|
state->Mode = SVC32MODE; |
||||
|
} |
||||
|
else { |
||||
|
state->Reg[15] = R15INTBITS | SVC26MODE; |
||||
|
state->Cpsr = INTBITS | SVC26MODE; |
||||
|
state->Mode = SVC26MODE; |
||||
|
} |
||||
|
//fprintf(stderr,"armul_reset 1: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);
|
||||
|
ARMul_CPSRAltered (state); |
||||
|
state->Bank = SVCBANK; |
||||
|
FLUSHPIPE; |
||||
|
|
||||
|
state->EndCondition = 0; |
||||
|
state->ErrorCode = 0; |
||||
|
|
||||
|
//fprintf(stderr,"armul_reset 2: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);
|
||||
|
state->NresetSig = HIGH; |
||||
|
state->NfiqSig = HIGH; |
||||
|
state->NirqSig = HIGH; |
||||
|
state->NtransSig = (state->Mode & 3) ? HIGH : LOW; |
||||
|
state->abortSig = LOW; |
||||
|
state->AbortAddr = 1; |
||||
|
|
||||
|
state->NumInstrs = 0; |
||||
|
state->NumNcycles = 0; |
||||
|
state->NumScycles = 0; |
||||
|
state->NumIcycles = 0; |
||||
|
state->NumCcycles = 0; |
||||
|
state->NumFcycles = 0; |
||||
|
|
||||
|
//fprintf(stderr,"armul_reset 3: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);
|
||||
|
mmu_reset (state); |
||||
|
//fprintf(stderr,"armul_reset 4: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);
|
||||
|
|
||||
|
//mem_reset (state); /* move to memory/ram.c */
|
||||
|
|
||||
|
//fprintf(stderr,"armul_reset 5: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);
|
||||
|
/*remove later. walimis 03.7.17 */ |
||||
|
//io_reset(state);
|
||||
|
//lcd_disable(state);
|
||||
|
|
||||
|
/*ywc 2005-04-07 move from ARMul_NewState , because skyeye_config.no_dbct will
|
||||
|
*be configured in skyeye_option_init and it is called after ARMul_NewState*/ |
||||
|
state->tea_break_ok = 0; |
||||
|
state->tea_break_addr = 0; |
||||
|
state->tea_pc = 0; |
||||
|
#ifdef DBCT
|
||||
|
if (!skyeye_config.no_dbct) { |
||||
|
//teawater add for arm2x86 2005.02.14-------------------------------------------
|
||||
|
if (arm2x86_init (state)) { |
||||
|
printf ("SKYEYE: arm2x86_init error\n"); |
||||
|
skyeye_exit (-1); |
||||
|
} |
||||
|
//AJ2D--------------------------------------------------------------------------
|
||||
|
} |
||||
|
#endif
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
/***************************************************************************\
|
||||
|
* Emulate the execution of an entire program. Start the correct emulator * |
||||
|
* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the * |
||||
|
* address of the last instruction that is executed. * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------
|
||||
|
#ifdef DBCT_TEST_SPEED
|
||||
|
static ARMul_State *dbct_test_speed_state = NULL; |
||||
|
static void |
||||
|
dbct_test_speed_sig(int signo) |
||||
|
{ |
||||
|
printf("\n0x%llx %llu\n", dbct_test_speed_state->instr_count, dbct_test_speed_state->instr_count); |
||||
|
skyeye_exit(0); |
||||
|
} |
||||
|
#endif //DBCT_TEST_SPEED
|
||||
|
//AJ2D--------------------------------------------------------------------------
|
||||
|
|
||||
|
ARMword |
||||
|
ARMul_DoProg (ARMul_State * state) |
||||
|
{ |
||||
|
ARMword pc = 0; |
||||
|
|
||||
|
/*
|
||||
|
* 2007-01-24 removed the term-io functions by Anthony Lee, |
||||
|
* moved to "device/uart/skyeye_uart_stdio.c". |
||||
|
*/ |
||||
|
|
||||
|
//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------
|
||||
|
#ifdef DBCT_TEST_SPEED
|
||||
|
{ |
||||
|
if (!dbct_test_speed_state) { |
||||
|
//init timer
|
||||
|
struct itimerval value; |
||||
|
struct sigaction act; |
||||
|
|
||||
|
dbct_test_speed_state = state; |
||||
|
state->instr_count = 0; |
||||
|
act.sa_handler = dbct_test_speed_sig; |
||||
|
act.sa_flags = SA_RESTART; |
||||
|
//cygwin don't support ITIMER_VIRTUAL or ITIMER_PROF
|
||||
|
#ifndef __CYGWIN__
|
||||
|
if (sigaction(SIGVTALRM, &act, NULL) == -1) { |
||||
|
#else
|
||||
|
if (sigaction(SIGALRM, &act, NULL) == -1) { |
||||
|
#endif //__CYGWIN__
|
||||
|
fprintf(stderr, "init timer error.\n"); |
||||
|
skyeye_exit(-1); |
||||
|
} |
||||
|
if (skyeye_config.dbct_test_speed_sec) { |
||||
|
value.it_value.tv_sec = skyeye_config.dbct_test_speed_sec; |
||||
|
} |
||||
|
else { |
||||
|
value.it_value.tv_sec = DBCT_TEST_SPEED_SEC; |
||||
|
} |
||||
|
printf("dbct_test_speed_sec = %ld\n", value.it_value.tv_sec); |
||||
|
value.it_value.tv_usec = 0; |
||||
|
value.it_interval.tv_sec = 0; |
||||
|
value.it_interval.tv_usec = 0; |
||||
|
#ifndef __CYGWIN__
|
||||
|
if (setitimer(ITIMER_VIRTUAL, &value, NULL) == -1) { |
||||
|
#else
|
||||
|
if (setitimer(ITIMER_REAL, &value, NULL) == -1) { |
||||
|
#endif //__CYGWIN__
|
||||
|
fprintf(stderr, "init timer error.\n"); |
||||
|
skyeye_exit(-1); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
#endif //DBCT_TEST_SPEED
|
||||
|
//AJ2D--------------------------------------------------------------------------
|
||||
|
state->Emulate = RUN; |
||||
|
while (state->Emulate != STOP) { |
||||
|
state->Emulate = RUN; |
||||
|
|
||||
|
/*ywc 2005-03-31 */ |
||||
|
if (state->prog32Sig && ARMul_MODE32BIT) { |
||||
|
#ifdef DBCT
|
||||
|
if (skyeye_config.no_dbct) { |
||||
|
pc = ARMul_Emulate32 (state); |
||||
|
} |
||||
|
else { |
||||
|
pc = ARMul_Emulate32_dbct (state); |
||||
|
} |
||||
|
#else
|
||||
|
pc = ARMul_Emulate32 (state); |
||||
|
#endif
|
||||
|
} |
||||
|
|
||||
|
else { |
||||
|
pc = ARMul_Emulate26 (state); |
||||
|
} |
||||
|
//chy 2006-02-22, should test debugmode first
|
||||
|
//chy 2006-04-14, put below codes in ARMul_Emulate
|
||||
|
#if 0
|
||||
|
if(debugmode) |
||||
|
if(remote_interrupt()) |
||||
|
state->Emulate = STOP; |
||||
|
#endif
|
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* 2007-01-24 removed the term-io functions by Anthony Lee, |
||||
|
* moved to "device/uart/skyeye_uart_stdio.c". |
||||
|
*/ |
||||
|
|
||||
|
return (pc); |
||||
|
} |
||||
|
|
||||
|
/***************************************************************************\
|
||||
|
* Emulate the execution of one instruction. Start the correct emulator * |
||||
|
* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the * |
||||
|
* address of the instruction that is executed. * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
ARMword |
||||
|
ARMul_DoInstr (ARMul_State * state) |
||||
|
{ |
||||
|
ARMword pc = 0; |
||||
|
|
||||
|
state->Emulate = ONCE; |
||||
|
|
||||
|
/*ywc 2005-03-31 */ |
||||
|
if (state->prog32Sig && ARMul_MODE32BIT) { |
||||
|
#ifdef DBCT
|
||||
|
if (skyeye_config.no_dbct) { |
||||
|
pc = ARMul_Emulate32 (state); |
||||
|
} |
||||
|
else { |
||||
|
//teawater add compile switch for DBCT GDB RSP function 2005.10.21--------------
|
||||
|
#ifndef DBCT_GDBRSP
|
||||
|
printf("DBCT GDBRSP function switch is off.\n"); |
||||
|
printf("To use this function, open \"#define DBCT_GDBRSP\" in arch/arm/common/armdefs.h & recompile skyeye.\n"); |
||||
|
skyeye_exit(-1); |
||||
|
#endif //DBCT_GDBRSP
|
||||
|
//AJ2D--------------------------------------------------------------------------
|
||||
|
pc = ARMul_Emulate32_dbct (state); |
||||
|
} |
||||
|
#else
|
||||
|
pc = ARMul_Emulate32 (state); |
||||
|
#endif
|
||||
|
} |
||||
|
|
||||
|
else |
||||
|
pc = ARMul_Emulate26 (state); |
||||
|
|
||||
|
return (pc); |
||||
|
} |
||||
|
|
||||
|
/***************************************************************************\
|
||||
|
* This routine causes an Abort to occur, including selecting the correct * |
||||
|
* mode, register bank, and the saving of registers. Call with the * |
||||
|
* appropriate vector's memory address (0,4,8 ....) * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
//void
|
||||
|
//ARMul_Abort (ARMul_State * state, ARMword vector)
|
||||
|
//{
|
||||
|
// ARMword temp;
|
||||
|
// int isize = INSN_SIZE;
|
||||
|
// int esize = (TFLAG ? 0 : 4);
|
||||
|
// int e2size = (TFLAG ? -4 : 0);
|
||||
|
//
|
||||
|
// state->Aborted = FALSE;
|
||||
|
//
|
||||
|
// if (state->prog32Sig)
|
||||
|
// if (ARMul_MODE26BIT)
|
||||
|
// temp = R15PC;
|
||||
|
// else
|
||||
|
// temp = state->Reg[15];
|
||||
|
// else
|
||||
|
// temp = R15PC | ECC | ER15INT | EMODE;
|
||||
|
//
|
||||
|
// switch (vector) {
|
||||
|
// case ARMul_ResetV: /* RESET */
|
||||
|
// SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE,
|
||||
|
// 0);
|
||||
|
// break;
|
||||
|
// case ARMul_UndefinedInstrV: /* Undefined Instruction */
|
||||
|
// SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE,
|
||||
|
// isize);
|
||||
|
// break;
|
||||
|
// case ARMul_SWIV: /* Software Interrupt */
|
||||
|
// SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE,
|
||||
|
// isize);
|
||||
|
// break;
|
||||
|
// case ARMul_PrefetchAbortV: /* Prefetch Abort */
|
||||
|
// state->AbortAddr = 1;
|
||||
|
// SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
|
||||
|
// esize);
|
||||
|
// break;
|
||||
|
// case ARMul_DataAbortV: /* Data Abort */
|
||||
|
// SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
|
||||
|
// e2size);
|
||||
|
// break;
|
||||
|
// case ARMul_AddrExceptnV: /* Address Exception */
|
||||
|
// SETABORT (IBIT, SVC26MODE, isize);
|
||||
|
// break;
|
||||
|
// case ARMul_IRQV: /* IRQ */
|
||||
|
// //chy 2003-09-02 the if sentence seems no use
|
||||
|
//#if 0
|
||||
|
// if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp)
|
||||
|
// || (temp & ARMul_CP13_R0_IRQ))
|
||||
|
//#endif
|
||||
|
// SETABORT (IBIT,
|
||||
|
// state->prog32Sig ? IRQ32MODE : IRQ26MODE,
|
||||
|
// esize);
|
||||
|
// break;
|
||||
|
// case ARMul_FIQV: /* FIQ */
|
||||
|
// //chy 2003-09-02 the if sentence seems no use
|
||||
|
//#if 0
|
||||
|
// if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp)
|
||||
|
// || (temp & ARMul_CP13_R0_FIQ))
|
||||
|
//#endif
|
||||
|
// SETABORT (INTBITS,
|
||||
|
// state->prog32Sig ? FIQ32MODE : FIQ26MODE,
|
||||
|
// esize);
|
||||
|
// break;
|
||||
|
// }
|
||||
|
//
|
||||
|
// if (ARMul_MODE32BIT) {
|
||||
|
// if (state->mmu.control & CONTROL_VECTOR)
|
||||
|
// vector += 0xffff0000; //for v4 high exception address
|
||||
|
// if (state->vector_remap_flag)
|
||||
|
// vector += state->vector_remap_addr; /* support some remap function in LPC processor */
|
||||
|
// ARMul_SetR15 (state, vector);
|
||||
|
// }
|
||||
|
// else
|
||||
|
// ARMul_SetR15 (state, R15CCINTMODE | vector);
|
||||
|
//}
|
||||
@ -0,0 +1,241 @@ |
|||||
|
/*
|
||||
|
armmmu.c - Memory Management Unit emulation. |
||||
|
ARMulator extensions for the ARM7100 family. |
||||
|
Copyright (C) 1999 Ben Williamson |
||||
|
|
||||
|
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 <assert.h>
|
||||
|
#include <string.h>
|
||||
|
#include "armdefs.h"
|
||||
|
/* two header for arm disassemble */ |
||||
|
//#include "skyeye_arch.h"
|
||||
|
#include "armcpu.h"
|
||||
|
|
||||
|
|
||||
|
extern mmu_ops_t xscale_mmu_ops; |
||||
|
exception_t arm_mmu_write(short size, u32 addr, uint32_t *value); |
||||
|
exception_t arm_mmu_read(short size, u32 addr, uint32_t *value); |
||||
|
#define MMU_OPS (state->mmu.ops)
|
||||
|
ARMword skyeye_cachetype = -1; |
||||
|
|
||||
|
int |
||||
|
mmu_init (ARMul_State * state) |
||||
|
{ |
||||
|
int ret; |
||||
|
|
||||
|
state->mmu.control = 0x70; |
||||
|
state->mmu.translation_table_base = 0xDEADC0DE; |
||||
|
state->mmu.domain_access_control = 0xDEADC0DE; |
||||
|
state->mmu.fault_status = 0; |
||||
|
state->mmu.fault_address = 0; |
||||
|
state->mmu.process_id = 0; |
||||
|
|
||||
|
switch (state->cpu->cpu_val & state->cpu->cpu_mask) { |
||||
|
case SA1100: |
||||
|
case SA1110: |
||||
|
SKYEYE_INFO("SKYEYE: use sa11xx mmu ops\n"); |
||||
|
state->mmu.ops = sa_mmu_ops; |
||||
|
break; |
||||
|
case PXA250: |
||||
|
case PXA270: //xscale
|
||||
|
SKYEYE_INFO ("SKYEYE: use xscale mmu ops\n"); |
||||
|
state->mmu.ops = xscale_mmu_ops; |
||||
|
break; |
||||
|
case 0x41807200: //arm720t
|
||||
|
case 0x41007700: //arm7tdmi
|
||||
|
case 0x41007100: //arm7100
|
||||
|
SKYEYE_INFO ( "SKYEYE: use arm7100 mmu ops\n"); |
||||
|
state->mmu.ops = arm7100_mmu_ops; |
||||
|
break; |
||||
|
case 0x41009200: |
||||
|
SKYEYE_INFO ("SKYEYE: use arm920t mmu ops\n"); |
||||
|
state->mmu.ops = arm920t_mmu_ops; |
||||
|
break; |
||||
|
case 0x41069260: |
||||
|
SKYEYE_INFO ("SKYEYE: use arm926ejs mmu ops\n"); |
||||
|
state->mmu.ops = arm926ejs_mmu_ops; |
||||
|
break; |
||||
|
/* case 0x560f5810: */ |
||||
|
case 0x0007b000: |
||||
|
SKYEYE_INFO ("SKYEYE: use arm11jzf-s mmu ops\n"); |
||||
|
state->mmu.ops = arm1176jzf_s_mmu_ops; |
||||
|
break; |
||||
|
|
||||
|
case 0xc090: |
||||
|
SKYEYE_INFO ("SKYEYE: use cortex_a9 mmu ops\n"); |
||||
|
state->mmu.ops = cortex_a9_mmu_ops; |
||||
|
break; |
||||
|
default: |
||||
|
fprintf (stderr, |
||||
|
"SKYEYE: armmmu.c : mmu_init: unknown cpu_val&cpu_mask 0x%x\n", |
||||
|
state->cpu->cpu_val & state->cpu->cpu_mask); |
||||
|
skyeye_exit (-1); |
||||
|
break; |
||||
|
|
||||
|
}; |
||||
|
ret = state->mmu.ops.init (state); |
||||
|
state->mmu_inited = (ret == 0); |
||||
|
/* initialize mmu_read and mmu_write for disassemble */ |
||||
|
skyeye_config_t *config = get_current_config(); |
||||
|
generic_arch_t *arch_instance = get_arch_instance(config->arch->arch_name); |
||||
|
arch_instance->mmu_read = arm_mmu_read; |
||||
|
arch_instance->mmu_write = arm_mmu_write; |
||||
|
|
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
mmu_reset (ARMul_State * state) |
||||
|
{ |
||||
|
if (state->mmu_inited) |
||||
|
mmu_exit (state); |
||||
|
return mmu_init (state); |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
mmu_exit (ARMul_State * state) |
||||
|
{ |
||||
|
MMU_OPS.exit (state); |
||||
|
state->mmu_inited = 0; |
||||
|
} |
||||
|
|
||||
|
fault_t |
||||
|
mmu_read_byte (ARMul_State * state, ARMword virt_addr, ARMword * data) |
||||
|
{ |
||||
|
return MMU_OPS.read_byte (state, virt_addr, data); |
||||
|
}; |
||||
|
|
||||
|
fault_t |
||||
|
mmu_read_halfword (ARMul_State * state, ARMword virt_addr, ARMword * data) |
||||
|
{ |
||||
|
return MMU_OPS.read_halfword (state, virt_addr, data); |
||||
|
}; |
||||
|
|
||||
|
fault_t |
||||
|
mmu_read_word (ARMul_State * state, ARMword virt_addr, ARMword * data) |
||||
|
{ |
||||
|
return MMU_OPS.read_word (state, virt_addr, data); |
||||
|
}; |
||||
|
|
||||
|
fault_t |
||||
|
mmu_write_byte (ARMul_State * state, ARMword virt_addr, ARMword data) |
||||
|
{ |
||||
|
fault_t fault; |
||||
|
//static int count = 0;
|
||||
|
//count ++;
|
||||
|
fault = MMU_OPS.write_byte (state, virt_addr, data); |
||||
|
return fault; |
||||
|
} |
||||
|
|
||||
|
fault_t |
||||
|
mmu_write_halfword (ARMul_State * state, ARMword virt_addr, ARMword data) |
||||
|
{ |
||||
|
fault_t fault; |
||||
|
//static int count = 0;
|
||||
|
//count ++;
|
||||
|
fault = MMU_OPS.write_halfword (state, virt_addr, data); |
||||
|
return fault; |
||||
|
} |
||||
|
|
||||
|
fault_t |
||||
|
mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data) |
||||
|
{ |
||||
|
fault_t fault; |
||||
|
fault = MMU_OPS.write_word (state, virt_addr, data); |
||||
|
|
||||
|
/*used for debug for MMU*
|
||||
|
|
||||
|
if (!fault){ |
||||
|
ARMword tmp; |
||||
|
|
||||
|
if (mmu_read_word(state, virt_addr, &tmp)){ |
||||
|
err_msg("load back\n"); |
||||
|
exit(-1); |
||||
|
}else{ |
||||
|
if (tmp != data){ |
||||
|
err_msg("load back not equal %d %x\n", count, virt_addr); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
*/ |
||||
|
|
||||
|
return fault; |
||||
|
}; |
||||
|
|
||||
|
fault_t |
||||
|
mmu_load_instr (ARMul_State * state, ARMword virt_addr, ARMword * instr) |
||||
|
{ |
||||
|
return MMU_OPS.load_instr (state, virt_addr, instr); |
||||
|
} |
||||
|
|
||||
|
ARMword |
||||
|
mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value) |
||||
|
{ |
||||
|
return MMU_OPS.mrc (state, instr, value); |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
mmu_mcr (ARMul_State * state, ARMword instr, ARMword value) |
||||
|
{ |
||||
|
MMU_OPS.mcr (state, instr, value); |
||||
|
} |
||||
|
|
||||
|
/*ywc 20050416*/ |
||||
|
int |
||||
|
mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr, ARMword * phys_addr) |
||||
|
{ |
||||
|
return (MMU_OPS.v2p_dbct (state, virt_addr, phys_addr)); |
||||
|
} |
||||
|
|
||||
|
/* dis_mmu_read for disassemble */ |
||||
|
exception_t arm_mmu_read(short size, generic_address_t addr, uint32_t * value) |
||||
|
{ |
||||
|
ARMul_State *state; |
||||
|
ARM_CPU_State *cpu = get_current_cpu(); |
||||
|
state = &cpu->core[0]; |
||||
|
switch(size){ |
||||
|
case 8: |
||||
|
MMU_OPS.read_byte (state, addr, value); |
||||
|
break; |
||||
|
case 16: |
||||
|
case 32: |
||||
|
break; |
||||
|
default: |
||||
|
printf("In %s error size %d Line %d\n", __func__, size, __LINE__); |
||||
|
break; |
||||
|
} |
||||
|
return No_exp; |
||||
|
} |
||||
|
/* dis_mmu_write for disassemble */ |
||||
|
exception_t arm_mmu_write(short size, generic_address_t addr, uint32_t *value) |
||||
|
{ |
||||
|
ARMul_State *state; |
||||
|
ARM_CPU_State *cpu = get_current_cpu(); |
||||
|
state = &cpu->core[0]; |
||||
|
switch(size){ |
||||
|
case 8: |
||||
|
MMU_OPS.write_byte (state, addr, value); |
||||
|
break; |
||||
|
case 16: |
||||
|
case 32: |
||||
|
break; |
||||
|
default: |
||||
|
printf("In %s error size %d Line %d\n", __func__, size, __LINE__); |
||||
|
break; |
||||
|
} |
||||
|
return No_exp; |
||||
|
} |
||||
@ -0,0 +1,254 @@ |
|||||
|
/* |
||||
|
armmmu.c - Memory Management Unit emulation. |
||||
|
ARMulator extensions for the ARM7100 family. |
||||
|
Copyright (C) 1999 Ben Williamson |
||||
|
|
||||
|
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 |
||||
|
*/ |
||||
|
|
||||
|
#ifndef _ARMMMU_H_ |
||||
|
#define _ARMMMU_H_ |
||||
|
|
||||
|
|
||||
|
#define WORD_SHT 2 |
||||
|
#define WORD_SIZE (1<<WORD_SHT) |
||||
|
/* The MMU is accessible with MCR and MRC operations to copro 15: */ |
||||
|
|
||||
|
#define MMU_COPRO (15) |
||||
|
|
||||
|
/* Register numbers in the MMU: */ |
||||
|
|
||||
|
typedef enum mmu_regnum_t |
||||
|
{ |
||||
|
MMU_ID = 0, |
||||
|
MMU_CONTROL = 1, |
||||
|
MMU_TRANSLATION_TABLE_BASE = 2, |
||||
|
MMU_DOMAIN_ACCESS_CONTROL = 3, |
||||
|
MMU_FAULT_STATUS = 5, |
||||
|
MMU_FAULT_ADDRESS = 6, |
||||
|
MMU_CACHE_OPS = 7, |
||||
|
MMU_TLB_OPS = 8, |
||||
|
MMU_CACHE_LOCKDOWN = 9, |
||||
|
MMU_TLB_LOCKDOWN = 10, |
||||
|
MMU_PID = 13, |
||||
|
|
||||
|
/*MMU_V4 */ |
||||
|
MMU_V4_CACHE_OPS = 7, |
||||
|
MMU_V4_TLB_OPS = 8, |
||||
|
|
||||
|
/*MMU_V3 */ |
||||
|
MMU_V3_FLUSH_TLB = 5, |
||||
|
MMU_V3_FLUSH_TLB_ENTRY = 6, |
||||
|
MMU_V3_FLUSH_CACHE = 7, |
||||
|
|
||||
|
/*MMU Intel SA-1100 */ |
||||
|
MMU_SA_RB_OPS = 9, |
||||
|
MMU_SA_DEBUG = 14, |
||||
|
MMU_SA_CP15_R15 = 15, |
||||
|
//chy 2003-08-24 |
||||
|
/*Intel xscale CP15 */ |
||||
|
XSCALE_CP15_CACHE_TYPE = 0, |
||||
|
XSCALE_CP15_AUX_CONTROL = 1, |
||||
|
XSCALE_CP15_COPRO_ACCESS = 15, |
||||
|
|
||||
|
} mmu_regnum_t; |
||||
|
|
||||
|
/* Bits in the control register */ |
||||
|
|
||||
|
#define CONTROL_MMU (1<<0) |
||||
|
#define CONTROL_ALIGN_FAULT (1<<1) |
||||
|
#define CONTROL_CACHE (1<<2) |
||||
|
#define CONTROL_DATA_CACHE (1<<2) |
||||
|
#define CONTROL_WRITE_BUFFER (1<<3) |
||||
|
#define CONTROL_BIG_ENDIAN (1<<7) |
||||
|
#define CONTROL_SYSTEM (1<<8) |
||||
|
#define CONTROL_ROM (1<<9) |
||||
|
#define CONTROL_UNDEFINED (1<<10) |
||||
|
#define CONTROL_BRANCH_PREDICT (1<<11) |
||||
|
#define CONTROL_INSTRUCTION_CACHE (1<<12) |
||||
|
#define CONTROL_VECTOR (1<<13) |
||||
|
#define CONTROL_RR (1<<14) |
||||
|
#define CONTROL_L4 (1<<15) |
||||
|
#define CONTROL_XP (1<<23) |
||||
|
#define CONTROL_EE (1<<25) |
||||
|
|
||||
|
/*Macro defines for MMU state*/ |
||||
|
#define MMU_CTL (state->mmu.control) |
||||
|
#define MMU_Enabled (state->mmu.control & CONTROL_MMU) |
||||
|
#define MMU_Disabled (!(MMU_Enabled)) |
||||
|
#define MMU_Aligned (state->mmu.control & CONTROL_ALIGN_FAULT) |
||||
|
|
||||
|
#define MMU_ICacheEnabled (MMU_CTL & CONTROL_INSTRUCTION_CACHE) |
||||
|
#define MMU_ICacheDisabled (!(MMU_ICacheDisabled)) |
||||
|
|
||||
|
#define MMU_DCacheEnabled (MMU_CTL & CONTROL_DATA_CACHE) |
||||
|
#define MMU_DCacheDisabled (!(MMU_DCacheEnabled)) |
||||
|
|
||||
|
#define MMU_CacheEnabled (MMU_CTL & CONTROL_CACHE) |
||||
|
#define MMU_CacheDisabled (!(MMU_CacheEnabled)) |
||||
|
|
||||
|
#define MMU_WBEnabled (MMU_CTL & CONTROL_WRITE_BUFFER) |
||||
|
#define MMU_WBDisabled (!(MMU_WBEnabled)) |
||||
|
|
||||
|
/*virt_addr exchange according to CP15.R13(process id virtul mapping)*/ |
||||
|
#define PID_VA_MAP_MASK 0xfe000000 |
||||
|
#define mmu_pid_va_map(va) ({\ |
||||
|
ARMword ret; \ |
||||
|
if ((va) & PID_VA_MAP_MASK)\ |
||||
|
ret = (va); \ |
||||
|
else \ |
||||
|
ret = ((va) | (state->mmu.process_id & PID_VA_MAP_MASK));\ |
||||
|
ret;\ |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
/* FS[3:0] in the fault status register: */ |
||||
|
|
||||
|
typedef enum fault_t |
||||
|
{ |
||||
|
NO_FAULT = 0x0, |
||||
|
ALIGNMENT_FAULT = 0x1, |
||||
|
|
||||
|
SECTION_TRANSLATION_FAULT = 0x5, |
||||
|
PAGE_TRANSLATION_FAULT = 0x7, |
||||
|
SECTION_DOMAIN_FAULT = 0x9, |
||||
|
PAGE_DOMAIN_FAULT = 0xB, |
||||
|
SECTION_PERMISSION_FAULT = 0xD, |
||||
|
SUBPAGE_PERMISSION_FAULT = 0xF, |
||||
|
|
||||
|
/* defined by skyeye */ |
||||
|
TLB_READ_MISS = 0x30, |
||||
|
TLB_WRITE_MISS = 0x40, |
||||
|
|
||||
|
} fault_t; |
||||
|
|
||||
|
typedef struct mmu_ops_s |
||||
|
{ |
||||
|
/*initilization */ |
||||
|
int (*init) (ARMul_State * state); |
||||
|
/*free on exit */ |
||||
|
void (*exit) (ARMul_State * state); |
||||
|
/*read byte data */ |
||||
|
fault_t (*read_byte) (ARMul_State * state, ARMword va, |
||||
|
ARMword * data); |
||||
|
/*write byte data */ |
||||
|
fault_t (*write_byte) (ARMul_State * state, ARMword va, |
||||
|
ARMword data); |
||||
|
/*read halfword data */ |
||||
|
fault_t (*read_halfword) (ARMul_State * state, ARMword va, |
||||
|
ARMword * data); |
||||
|
/*write halfword data */ |
||||
|
fault_t (*write_halfword) (ARMul_State * state, ARMword va, |
||||
|
ARMword data); |
||||
|
/*read word data */ |
||||
|
fault_t (*read_word) (ARMul_State * state, ARMword va, |
||||
|
ARMword * data); |
||||
|
/*write word data */ |
||||
|
fault_t (*write_word) (ARMul_State * state, ARMword va, |
||||
|
ARMword data); |
||||
|
/*load instr */ |
||||
|
fault_t (*load_instr) (ARMul_State * state, ARMword va, |
||||
|
ARMword * instr); |
||||
|
/*mcr */ |
||||
|
ARMword (*mcr) (ARMul_State * state, ARMword instr, ARMword val); |
||||
|
/*mrc */ |
||||
|
ARMword (*mrc) (ARMul_State * state, ARMword instr, ARMword * val); |
||||
|
|
||||
|
/*ywc 2005-04-16 convert virtual address to physics address */ |
||||
|
int (*v2p_dbct) (ARMul_State * state, ARMword virt_addr, |
||||
|
ARMword * phys_addr); |
||||
|
} mmu_ops_t; |
||||
|
|
||||
|
|
||||
|
#include "mmu/tlb.h" |
||||
|
#include "mmu/rb.h" |
||||
|
#include "mmu/wb.h" |
||||
|
#include "mmu/cache.h" |
||||
|
|
||||
|
/*special process mmu.h*/ |
||||
|
//#include "mmu/sa_mmu.h" |
||||
|
//#include "mmu/arm7100_mmu.h" |
||||
|
//#include "mmu/arm920t_mmu.h" |
||||
|
//#include "mmu/arm926ejs_mmu.h" |
||||
|
#include "mmu/arm1176jzf_s_mmu.h" |
||||
|
//#include "mmu/cortex_a9_mmu.h" |
||||
|
|
||||
|
typedef struct mmu_state_t |
||||
|
{ |
||||
|
ARMword control; |
||||
|
ARMword translation_table_base; |
||||
|
/* dyf 201-08-11 for arm1176 */ |
||||
|
ARMword auxiliary_control; |
||||
|
ARMword coprocessor_access_control; |
||||
|
ARMword translation_table_base0; |
||||
|
ARMword translation_table_base1; |
||||
|
ARMword translation_table_ctrl; |
||||
|
/* arm1176 end */ |
||||
|
|
||||
|
ARMword domain_access_control; |
||||
|
ARMword fault_status; |
||||
|
ARMword fault_statusi; /* prefetch fault status */ |
||||
|
ARMword fault_address; |
||||
|
ARMword last_domain; |
||||
|
ARMword process_id; |
||||
|
ARMword context_id; |
||||
|
ARMword thread_uro_id; |
||||
|
ARMword cache_locked_down; |
||||
|
ARMword tlb_locked_down; |
||||
|
//chy 2003-08-24 for xscale |
||||
|
ARMword cache_type; // 0 |
||||
|
ARMword aux_control; // 1 |
||||
|
ARMword copro_access; // 15 |
||||
|
|
||||
|
mmu_ops_t ops; |
||||
|
//union |
||||
|
//{ |
||||
|
//sa_mmu_t sa_mmu; |
||||
|
//arm7100_mmu_t arm7100_mmu; |
||||
|
//arm920t_mmu_t arm920t_mmu; |
||||
|
//arm926ejs_mmu_t arm926ejs_mmu; |
||||
|
//} u; |
||||
|
} mmu_state_t; |
||||
|
|
||||
|
int mmu_init (ARMul_State * state); |
||||
|
int mmu_reset (ARMul_State * state); |
||||
|
void mmu_exit (ARMul_State * state); |
||||
|
|
||||
|
fault_t mmu_read_word (ARMul_State * state, ARMword virt_addr, |
||||
|
ARMword * data); |
||||
|
fault_t mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data); |
||||
|
fault_t mmu_load_instr (ARMul_State * state, ARMword virt_addr, |
||||
|
ARMword * instr); |
||||
|
|
||||
|
ARMword mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value); |
||||
|
void mmu_mcr (ARMul_State * state, ARMword instr, ARMword value); |
||||
|
|
||||
|
/*ywc 20050416*/ |
||||
|
int mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr, |
||||
|
ARMword * phys_addr); |
||||
|
|
||||
|
fault_t |
||||
|
mmu_read_byte (ARMul_State * state, ARMword virt_addr, ARMword * data); |
||||
|
fault_t |
||||
|
mmu_read_halfword (ARMul_State * state, ARMword virt_addr, ARMword * data); |
||||
|
fault_t |
||||
|
mmu_read_word (ARMul_State * state, ARMword virt_addr, ARMword * data); |
||||
|
fault_t |
||||
|
mmu_write_byte (ARMul_State * state, ARMword virt_addr, ARMword data); |
||||
|
fault_t |
||||
|
mmu_write_halfword (ARMul_State * state, ARMword virt_addr, ARMword data); |
||||
|
fault_t |
||||
|
mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data); |
||||
|
#endif /* _ARMMMU_H_ */ |
||||
@ -0,0 +1,138 @@ |
|||||
|
/* armos.h -- ARMulator OS definitions: ARM6 Instruction Emulator. |
||||
|
Copyright (C) 1994 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 "bank_defs.h" |
||||
|
//#include "dyncom/defines.h" |
||||
|
|
||||
|
//typedef struct mmap_area{ |
||||
|
// mem_bank_t bank; |
||||
|
// void *mmap_addr; |
||||
|
// struct mmap_area *next; |
||||
|
//}mmap_area_t; |
||||
|
|
||||
|
#if FAST_MEMORY |
||||
|
/* in user mode, mmap_base will be on initial brk, |
||||
|
set at the first mmap request */ |
||||
|
#define mmap_base -1 |
||||
|
#else |
||||
|
#define mmap_base 0x50000000 |
||||
|
#endif |
||||
|
static long mmap_next_base = mmap_base; |
||||
|
|
||||
|
//static mmap_area_t* new_mmap_area(int sim_addr, int len); |
||||
|
static char mmap_mem_write(short size, int addr, uint32_t value); |
||||
|
static char mmap_mem_read(short size, int addr, uint32_t * value); |
||||
|
|
||||
|
/***************************************************************************\ |
||||
|
* SWI numbers * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
#define SWI_Syscall 0x0 |
||||
|
#define SWI_Exit 0x1 |
||||
|
#define SWI_Read 0x3 |
||||
|
#define SWI_Write 0x4 |
||||
|
#define SWI_Open 0x5 |
||||
|
#define SWI_Close 0x6 |
||||
|
#define SWI_Seek 0x13 |
||||
|
#define SWI_Rename 0x26 |
||||
|
#define SWI_Break 0x11 |
||||
|
|
||||
|
#define SWI_Times 0x2b |
||||
|
#define SWI_Brk 0x2d |
||||
|
|
||||
|
#define SWI_Mmap 0x5a |
||||
|
#define SWI_Munmap 0x5b |
||||
|
#define SWI_Mmap2 0xc0 |
||||
|
|
||||
|
#define SWI_GetUID32 0xc7 |
||||
|
#define SWI_GetGID32 0xc8 |
||||
|
#define SWI_GetEUID32 0xc9 |
||||
|
#define SWI_GetEGID32 0xca |
||||
|
|
||||
|
#define SWI_ExitGroup 0xf8 |
||||
|
|
||||
|
#if 0 |
||||
|
#define SWI_Time 0xd |
||||
|
#define SWI_Clock 0x61 |
||||
|
#define SWI_Time 0x63 |
||||
|
#define SWI_Remove 0x64 |
||||
|
#define SWI_Rename 0x65 |
||||
|
#define SWI_Flen 0x6c |
||||
|
#endif |
||||
|
|
||||
|
#define SWI_Uname 0x7a |
||||
|
#define SWI_Fcntl 0xdd |
||||
|
#define SWI_Fstat64 0xc5 |
||||
|
#define SWI_Gettimeofday 0x4e |
||||
|
#define SWI_Set_tls 0xf0005 |
||||
|
|
||||
|
#define SWI_Breakpoint 0x180000 /* see gdb's tm-arm.h */ |
||||
|
|
||||
|
/***************************************************************************\ |
||||
|
* SWI structures * |
||||
|
\***************************************************************************/ |
||||
|
|
||||
|
/* Arm binaries (for now) only support 32 bit, and expect to receive |
||||
|
32-bit compliant structure in return of a systen call. Because |
||||
|
we use host system calls to emulate system calls, the returned |
||||
|
structure can be 32-bit compliant or 64-bit compliant, depending |
||||
|
on the OS running skyeye. Therefore, we need a fixed size structure |
||||
|
adapted to arm.*/ |
||||
|
|
||||
|
/* Borrowed from qemu */ |
||||
|
struct target_stat64 { |
||||
|
unsigned short st_dev; |
||||
|
unsigned char __pad0[10]; |
||||
|
uint32_t __st_ino; |
||||
|
unsigned int st_mode; |
||||
|
unsigned int st_nlink; |
||||
|
uint32_t st_uid; |
||||
|
uint32_t st_gid; |
||||
|
unsigned short st_rdev; |
||||
|
unsigned char __pad3[10]; |
||||
|
unsigned char __pad31[4]; |
||||
|
long long st_size; |
||||
|
uint32_t st_blksize; |
||||
|
unsigned char __pad32[4]; |
||||
|
uint32_t st_blocks; |
||||
|
uint32_t __pad4; |
||||
|
uint32_t st32_atime; |
||||
|
uint32_t __pad5; |
||||
|
uint32_t st32_mtime; |
||||
|
uint32_t __pad6; |
||||
|
uint32_t st32_ctime; |
||||
|
uint32_t __pad7; |
||||
|
unsigned long long st_ino; |
||||
|
};// __attribute__((packed)); |
||||
|
|
||||
|
struct target_tms32 { |
||||
|
uint32_t tms_utime; |
||||
|
uint32_t tms_stime; |
||||
|
uint32_t tms_cutime; |
||||
|
uint32_t tms_cstime; |
||||
|
}; |
||||
|
|
||||
|
struct target_timeval32 { |
||||
|
uint32_t tv_sec; /* seconds */ |
||||
|
uint32_t tv_usec; /* microseconds */ |
||||
|
}; |
||||
|
|
||||
|
struct target_timezone32 { |
||||
|
int32_t tz_minuteswest; /* minutes west of Greenwich */ |
||||
|
int32_t tz_dsttime; /* type of DST correction */ |
||||
|
}; |
||||
|
|
||||
1165
src/core/src/arm/mmu/arm1176jzf_s_mmu.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,37 @@ |
|||||
|
/* |
||||
|
arm1176JZF-S_mmu.h - ARM1176JZF-S Memory Management Unit emulation. |
||||
|
|
||||
|
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 |
||||
|
*/ |
||||
|
|
||||
|
#ifndef _ARM1176JZF_S_MMU_H_ |
||||
|
#define _ARM1176JZF_S_MMU_H_ |
||||
|
|
||||
|
#if 0 |
||||
|
typedef struct arm1176jzf-s_mmu_s |
||||
|
{ |
||||
|
tlb_t i_tlb; |
||||
|
cache_t i_cache; |
||||
|
|
||||
|
tlb_t d_tlb; |
||||
|
cache_t d_cache; |
||||
|
wb_t wb_t; |
||||
|
} arm1176jzf-s_mmu_t; |
||||
|
#endif |
||||
|
extern mmu_ops_t arm1176jzf_s_mmu_ops; |
||||
|
|
||||
|
ARMword |
||||
|
arm1176jzf_s_mmu_mrc (ARMul_State *state, ARMword instr, ARMword *value); |
||||
|
#endif /*_ARM1176JZF_S_MMU_H_*/ |
||||
@ -0,0 +1,168 @@ |
|||||
|
#ifndef _MMU_CACHE_H_ |
||||
|
#define _MMU_CACHE_H_ |
||||
|
|
||||
|
typedef struct cache_line_t |
||||
|
{ |
||||
|
ARMword tag; /* cache line align address | |
||||
|
bit2: last half dirty |
||||
|
bit1: first half dirty |
||||
|
bit0: cache valid flag |
||||
|
*/ |
||||
|
ARMword pa; /*physical address */ |
||||
|
ARMword *data; /*array of cached data */ |
||||
|
} cache_line_t; |
||||
|
#define TAG_VALID_FLAG 0x00000001 |
||||
|
#define TAG_FIRST_HALF_DIRTY 0x00000002 |
||||
|
#define TAG_LAST_HALF_DIRTY 0x00000004 |
||||
|
|
||||
|
/*cache set association*/ |
||||
|
typedef struct cache_set_s |
||||
|
{ |
||||
|
cache_line_t *lines; |
||||
|
int cycle; |
||||
|
} cache_set_t; |
||||
|
|
||||
|
enum |
||||
|
{ |
||||
|
CACHE_WRITE_BACK, |
||||
|
CACHE_WRITE_THROUGH, |
||||
|
}; |
||||
|
|
||||
|
typedef struct cache_s |
||||
|
{ |
||||
|
int width; /*bytes in a line */ |
||||
|
int way; /*way of set asscociate */ |
||||
|
int set; /*num of set */ |
||||
|
int w_mode; /*write back or write through */ |
||||
|
//int a_mode; /*alloc mode: random or round-bin*/ |
||||
|
cache_set_t *sets; |
||||
|
/**/} cache_s; |
||||
|
|
||||
|
typedef struct cache_desc_s |
||||
|
{ |
||||
|
int width; |
||||
|
int way; |
||||
|
int set; |
||||
|
int w_mode; |
||||
|
// int a_mode; |
||||
|
} cache_desc_t; |
||||
|
|
||||
|
|
||||
|
/*virtual address to cache set index*/ |
||||
|
#define va_cache_set(va, cache_t) \ |
||||
|
(((va) / (cache_t)->width) & ((cache_t)->set - 1)) |
||||
|
/*virtual address to cahce line aligned*/ |
||||
|
#define va_cache_align(va, cache_t) \ |
||||
|
((va) & ~((cache_t)->width - 1)) |
||||
|
/*virtaul address to cache line word index*/ |
||||
|
#define va_cache_index(va, cache_t) \ |
||||
|
(((va) & ((cache_t)->width - 1)) >> WORD_SHT) |
||||
|
|
||||
|
/*see Page 558 in arm manual*/ |
||||
|
/*set/index format value to cache set value*/ |
||||
|
#define index_cache_set(index, cache_t) \ |
||||
|
(((index) / (cache_t)->width) & ((cache_t)->set - 1)) |
||||
|
|
||||
|
/*************************cache********************/ |
||||
|
/* mmu cache init |
||||
|
* |
||||
|
* @cache_t :cache_t to init |
||||
|
* @width :cache line width in byte |
||||
|
* @way :way of each cache set |
||||
|
* @set :cache set num |
||||
|
* @w_mode :cache w_mode |
||||
|
* |
||||
|
* $ -1: error |
||||
|
* 0: sucess |
||||
|
*/ |
||||
|
int |
||||
|
mmu_cache_init (cache_s * cache_t, int width, int way, int set, int w_mode); |
||||
|
|
||||
|
/* free a cache_t's inner data, the ptr self is not freed, |
||||
|
* when needed do like below: |
||||
|
* mmu_cache_exit(cache); |
||||
|
* free(cache_t); |
||||
|
* |
||||
|
* @cache_t : the cache_t to free |
||||
|
*/ |
||||
|
void mmu_cache_exit (cache_s * cache_t); |
||||
|
|
||||
|
/* mmu cache search |
||||
|
* |
||||
|
* @state :ARMul_State |
||||
|
* @cache_t :cache_t to search |
||||
|
* @va :virtual address |
||||
|
* |
||||
|
* $ NULL: no cache match |
||||
|
* cache :cache matched |
||||
|
* */ |
||||
|
cache_line_t *mmu_cache_search (ARMul_State * state, cache_s * cache_t, |
||||
|
ARMword va); |
||||
|
|
||||
|
/* mmu cache search by set/index |
||||
|
* |
||||
|
* @state :ARMul_State |
||||
|
* @cache_t :cache_t to search |
||||
|
* @index :set/index value. |
||||
|
* |
||||
|
* $ NULL: no cache match |
||||
|
* cache :cache matched |
||||
|
* */ |
||||
|
|
||||
|
cache_line_t *mmu_cache_search_by_index (ARMul_State * state, |
||||
|
cache_s * cache_t, ARMword index); |
||||
|
|
||||
|
/* mmu cache alloc |
||||
|
* |
||||
|
* @state :ARMul_State |
||||
|
* @cache_t :cache_t to alloc from |
||||
|
* @va :virtual address that require cache alloc, need not cache aligned |
||||
|
* @pa :physical address of va |
||||
|
* |
||||
|
* $ cache_alloced, always alloc OK |
||||
|
*/ |
||||
|
cache_line_t *mmu_cache_alloc (ARMul_State * state, cache_s * cache_t, |
||||
|
ARMword va, ARMword pa); |
||||
|
|
||||
|
/* mmu_cache_write_back write cache data to memory |
||||
|
* |
||||
|
* @state: |
||||
|
* @cache_t :cache_t of the cache line |
||||
|
* @cache : cache line |
||||
|
*/ |
||||
|
void |
||||
|
mmu_cache_write_back (ARMul_State * state, cache_s * cache_t, |
||||
|
cache_line_t * cache); |
||||
|
|
||||
|
/* mmu_cache_clean: clean a cache of va in cache_t |
||||
|
* |
||||
|
* @state :ARMul_State |
||||
|
* @cache_t :cache_t to clean |
||||
|
* @va :virtaul address |
||||
|
*/ |
||||
|
void mmu_cache_clean (ARMul_State * state, cache_s * cache_t, ARMword va); |
||||
|
void |
||||
|
mmu_cache_clean_by_index (ARMul_State * state, cache_s * cache_t, |
||||
|
ARMword index); |
||||
|
|
||||
|
/* mmu_cache_invalidate : invalidate a cache of va |
||||
|
* |
||||
|
* @state :ARMul_State |
||||
|
* @cache_t :cache_t to invalid |
||||
|
* @va :virt_addr to invalid |
||||
|
*/ |
||||
|
void |
||||
|
mmu_cache_invalidate (ARMul_State * state, cache_s * cache_t, ARMword va); |
||||
|
|
||||
|
void |
||||
|
mmu_cache_invalidate_by_index (ARMul_State * state, cache_s * cache_t, |
||||
|
ARMword index); |
||||
|
|
||||
|
void mmu_cache_invalidate_all (ARMul_State * state, cache_s * cache_t); |
||||
|
|
||||
|
void |
||||
|
mmu_cache_soft_flush (ARMul_State * state, cache_s * cache_t, ARMword pa); |
||||
|
|
||||
|
cache_line_t* mmu_cache_dirty_cache(ARMul_State * state, cache_s * cache_t); |
||||
|
|
||||
|
#endif /*_MMU_CACHE_H_*/ |
||||
@ -0,0 +1,55 @@ |
|||||
|
#ifndef _MMU_RB_H |
||||
|
#define _MMU_RB_H |
||||
|
|
||||
|
enum rb_type_t |
||||
|
{ |
||||
|
RB_INVALID = 0, //invalid |
||||
|
RB_1, //1 word |
||||
|
RB_4, //4 word |
||||
|
RB_8, //8 word |
||||
|
}; |
||||
|
|
||||
|
/*bytes of each rb_type*/ |
||||
|
extern ARMword rb_masks[]; |
||||
|
|
||||
|
#define RB_WORD_NUM 8 |
||||
|
typedef struct rb_entry_s |
||||
|
{ |
||||
|
ARMword data[RB_WORD_NUM]; //array to store data |
||||
|
ARMword va; //first word va |
||||
|
int type; //rb type |
||||
|
fault_t fault; //fault set by rb alloc |
||||
|
} rb_entry_t; |
||||
|
|
||||
|
typedef struct rb_s |
||||
|
{ |
||||
|
int num; |
||||
|
rb_entry_t *entrys; |
||||
|
} rb_s; |
||||
|
|
||||
|
/*mmu_rb_init |
||||
|
* @rb_t :rb_t to init |
||||
|
* @num :number of entry |
||||
|
* */ |
||||
|
int mmu_rb_init (rb_s * rb_t, int num); |
||||
|
|
||||
|
/*mmu_rb_exit*/ |
||||
|
void mmu_rb_exit (rb_s * rb_t); |
||||
|
|
||||
|
|
||||
|
/*mmu_rb_search |
||||
|
* @rb_t :rb_t to serach |
||||
|
* @va :va address to math |
||||
|
* |
||||
|
* $ NULL :not match |
||||
|
* NO-NULL: |
||||
|
* */ |
||||
|
rb_entry_t *mmu_rb_search (rb_s * rb_t, ARMword va); |
||||
|
|
||||
|
|
||||
|
void mmu_rb_invalidate_entry (rb_s * rb_t, int i); |
||||
|
void mmu_rb_invalidate_all (rb_s * rb_t); |
||||
|
void mmu_rb_load (ARMul_State * state, rb_s * rb_t, int i_rb, |
||||
|
int type, ARMword va); |
||||
|
|
||||
|
#endif /*_MMU_RB_H_*/ |
||||
@ -0,0 +1,94 @@ |
|||||
|
#ifndef _MMU_TLB_H_ |
||||
|
#define _MMU_TLB_H_ |
||||
|
|
||||
|
typedef enum tlb_mapping_t |
||||
|
{ |
||||
|
TLB_INVALID = 0, |
||||
|
TLB_SMALLPAGE = 1, |
||||
|
TLB_LARGEPAGE = 2, |
||||
|
TLB_SECTION = 3, |
||||
|
TLB_ESMALLPAGE = 4, |
||||
|
TLB_TINYPAGE = 5 |
||||
|
} tlb_mapping_t; |
||||
|
|
||||
|
extern ARMword tlb_masks[]; |
||||
|
|
||||
|
/* Permissions bits in a TLB entry: |
||||
|
* |
||||
|
* 31 12 11 10 9 8 7 6 5 4 3 2 1 0 |
||||
|
* +-------------+-----+-----+-----+-----+---+---+-------+ |
||||
|
* Page:| | ap3 | ap2 | ap1 | ap0 | C | B | | |
||||
|
* +-------------+-----+-----+-----+-----+---+---+-------+ |
||||
|
* |
||||
|
* 31 12 11 10 9 4 3 2 1 0 |
||||
|
* +-------------+-----+-----------------+---+---+-------+ |
||||
|
* Section: | | AP | | C | B | | |
||||
|
* +-------------+-----+-----------------+---+---+-------+ |
||||
|
*/ |
||||
|
|
||||
|
/* |
||||
|
section: |
||||
|
section base address [31:20] |
||||
|
AP - table 8-2, page 8-8 |
||||
|
domain |
||||
|
C,B |
||||
|
|
||||
|
page: |
||||
|
page base address [31:16] or [31:12] |
||||
|
ap[3:0] |
||||
|
domain (from L1) |
||||
|
C,B |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
typedef struct tlb_entry_t |
||||
|
{ |
||||
|
ARMword virt_addr; |
||||
|
ARMword phys_addr; |
||||
|
ARMword perms; |
||||
|
ARMword domain; |
||||
|
tlb_mapping_t mapping; |
||||
|
} tlb_entry_t; |
||||
|
|
||||
|
typedef struct tlb_s |
||||
|
{ |
||||
|
int num; /*num of tlb entry */ |
||||
|
int cycle; /*current tlb cycle */ |
||||
|
tlb_entry_t *entrys; |
||||
|
} tlb_s; |
||||
|
|
||||
|
|
||||
|
#define tlb_c_flag(tlb) \ |
||||
|
((tlb)->perms & 0x8) |
||||
|
#define tlb_b_flag(tlb) \ |
||||
|
((tlb)->perms & 0x4) |
||||
|
|
||||
|
#define tlb_va_to_pa(tlb, va) \ |
||||
|
(\ |
||||
|
{\ |
||||
|
ARMword mask = tlb_masks[tlb->mapping]; \ |
||||
|
(tlb->phys_addr & mask) | (va & ~mask);\ |
||||
|
}\ |
||||
|
) |
||||
|
|
||||
|
fault_t |
||||
|
check_access (ARMul_State * state, ARMword virt_addr, tlb_entry_t * tlb, |
||||
|
int read); |
||||
|
|
||||
|
fault_t |
||||
|
translate (ARMul_State * state, ARMword virt_addr, tlb_s * tlb_t, |
||||
|
tlb_entry_t ** tlb); |
||||
|
|
||||
|
int mmu_tlb_init (tlb_s * tlb_t, int num); |
||||
|
|
||||
|
void mmu_tlb_exit (tlb_s * tlb_t); |
||||
|
|
||||
|
void mmu_tlb_invalidate_all (ARMul_State * state, tlb_s * tlb_t); |
||||
|
|
||||
|
void |
||||
|
mmu_tlb_invalidate_entry (ARMul_State * state, tlb_s * tlb_t, ARMword addr); |
||||
|
|
||||
|
tlb_entry_t *mmu_tlb_search (ARMul_State * state, tlb_s * tlb_t, |
||||
|
ARMword virt_addr); |
||||
|
|
||||
|
#endif /*_MMU_TLB_H_*/ |
||||
@ -0,0 +1,63 @@ |
|||||
|
#ifndef _MMU_WB_H_ |
||||
|
#define _MMU_WB_H_ |
||||
|
|
||||
|
typedef struct wb_entry_s |
||||
|
{ |
||||
|
ARMword pa; //phy_addr |
||||
|
ARMbyte *data; //data |
||||
|
int nb; //number byte to write |
||||
|
} wb_entry_t; |
||||
|
|
||||
|
typedef struct wb_s |
||||
|
{ |
||||
|
int num; //number of wb_entry |
||||
|
int nb; //number of byte of each entry |
||||
|
int first; // |
||||
|
int last; // |
||||
|
int used; // |
||||
|
wb_entry_t *entrys; |
||||
|
} wb_s; |
||||
|
|
||||
|
typedef struct wb_desc_s |
||||
|
{ |
||||
|
int num; |
||||
|
int nb; |
||||
|
} wb_desc_t; |
||||
|
|
||||
|
/* wb_init |
||||
|
* @wb_t :wb_t to init |
||||
|
* @num :num of entrys |
||||
|
* @nw :num of word of each entry |
||||
|
* |
||||
|
* $ -1:error |
||||
|
* 0:ok |
||||
|
* */ |
||||
|
int mmu_wb_init (wb_s * wb_t, int num, int nb); |
||||
|
|
||||
|
|
||||
|
/* wb_exit |
||||
|
* @wb_t :wb_t to exit |
||||
|
* */ |
||||
|
void mmu_wb_exit (wb_s * wb); |
||||
|
|
||||
|
|
||||
|
/* wb_write_bytes :put bytess in Write Buffer |
||||
|
* @state: ARMul_State |
||||
|
* @wb_t: write buffer |
||||
|
* @pa: physical address |
||||
|
* @data: data ptr |
||||
|
* @n number of byte to write |
||||
|
* |
||||
|
* Note: write buffer merge is not implemented, can be done late |
||||
|
* */ |
||||
|
void |
||||
|
mmu_wb_write_bytess (ARMul_State * state, wb_s * wb_t, ARMword pa, |
||||
|
ARMbyte * data, int n); |
||||
|
|
||||
|
|
||||
|
/* wb_drain_all |
||||
|
* @wb_t wb_t to drain |
||||
|
* */ |
||||
|
void mmu_wb_drain_all (ARMul_State * state, wb_s * wb_t); |
||||
|
|
||||
|
#endif /*_MMU_WB_H_*/ |
||||
@ -0,0 +1,110 @@ |
|||||
|
#ifndef CORE_ARM_SKYEYE_DEFS_H_ |
||||
|
#define CORE_ARM_SKYEYE_DEFS_H_ |
||||
|
|
||||
|
#include "common.h" |
||||
|
|
||||
|
#define MODE32 |
||||
|
|
||||
|
typedef struct |
||||
|
{ |
||||
|
const char *cpu_arch_name; /*cpu architecture version name.e.g. armv4t */ |
||||
|
const char *cpu_name; /*cpu name. e.g. arm7tdmi or arm720t */ |
||||
|
u32 cpu_val; /*CPU value; also call MMU ID or processor id;see |
||||
|
ARM Architecture Reference Manual B2-6 */ |
||||
|
u32 cpu_mask; /*cpu_val's mask. */ |
||||
|
u32 cachetype; /*this cpu has what kind of cache */ |
||||
|
} cpu_config_t; |
||||
|
|
||||
|
typedef struct conf_object_s{ |
||||
|
char* objname; |
||||
|
void* obj; |
||||
|
char* class_name; |
||||
|
}conf_object_t; |
||||
|
|
||||
|
typedef enum{ |
||||
|
/* No exception */ |
||||
|
No_exp = 0, |
||||
|
/* Memory allocation exception */ |
||||
|
Malloc_exp, |
||||
|
/* File open exception */ |
||||
|
File_open_exp, |
||||
|
/* DLL open exception */ |
||||
|
Dll_open_exp, |
||||
|
/* Invalid argument exception */ |
||||
|
Invarg_exp, |
||||
|
/* Invalid module exception */ |
||||
|
Invmod_exp, |
||||
|
/* wrong format exception for config file parsing */ |
||||
|
Conf_format_exp, |
||||
|
/* some reference excess the predefiend range. Such as the index out of array range */ |
||||
|
Excess_range_exp, |
||||
|
/* Can not find the desirable result */ |
||||
|
Not_found_exp, |
||||
|
|
||||
|
/* Unknown exception */ |
||||
|
Unknown_exp |
||||
|
}exception_t; |
||||
|
|
||||
|
typedef enum { |
||||
|
Align = 0, |
||||
|
UnAlign |
||||
|
}align_t; |
||||
|
|
||||
|
typedef enum { |
||||
|
Little_endian = 0, |
||||
|
Big_endian |
||||
|
}endian_t; |
||||
|
//typedef int exception_t; |
||||
|
|
||||
|
typedef enum{ |
||||
|
Phys_addr = 0, |
||||
|
Virt_addr |
||||
|
}addr_type_t; |
||||
|
|
||||
|
typedef exception_t(*read_byte_t)(conf_object_t* target, u32 addr, void *buf, size_t count); |
||||
|
typedef exception_t(*write_byte_t)(conf_object_t* target, u32 addr, const void *buf, size_t count); |
||||
|
|
||||
|
typedef struct memory_space{ |
||||
|
conf_object_t* conf_obj; |
||||
|
read_byte_t read; |
||||
|
write_byte_t write; |
||||
|
}memory_space_intf; |
||||
|
|
||||
|
|
||||
|
/* |
||||
|
* a running instance for a specific archteciture. |
||||
|
*/ |
||||
|
typedef struct generic_arch_s |
||||
|
{ |
||||
|
char* arch_name; |
||||
|
void (*init) (void); |
||||
|
void (*reset) (void); |
||||
|
void (*step_once) (void); |
||||
|
void (*set_pc)(u32 addr); |
||||
|
u32 (*get_pc)(void); |
||||
|
u32 (*get_step)(void); |
||||
|
//chy 2004-04-15 |
||||
|
//int (*ICE_write_byte) (u32 addr, uint8_t v); |
||||
|
//int (*ICE_read_byte)(u32 addr, uint8_t *pv); |
||||
|
u32 (*get_regval_by_id)(int id); |
||||
|
u32 (*get_regnum)(void); |
||||
|
char* (*get_regname_by_id)(int id); |
||||
|
exception_t (*set_regval_by_id)(int id, u32 value); |
||||
|
/* |
||||
|
* read a data by virtual address. |
||||
|
*/ |
||||
|
exception_t (*mmu_read)(short size, u32 addr, u32 * value); |
||||
|
/* |
||||
|
* write a data by a virtual address. |
||||
|
*/ |
||||
|
exception_t (*mmu_write)(short size, u32 addr, u32 value); |
||||
|
/** |
||||
|
* get a signal from external |
||||
|
*/ |
||||
|
//exception_t (*signal)(interrupt_signal_t* signal); |
||||
|
|
||||
|
endian_t endianess; |
||||
|
align_t alignment; |
||||
|
} generic_arch_t; |
||||
|
|
||||
|
#endif |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue