mirror of
https://github.com/PabloMK7/citra.git
synced 2024-11-30 19:30:17 +00:00
added ARMulator/skyeye ARM11 core to the project
This commit is contained in:
parent
cdbe6557e8
commit
7dcfb9c1cf
18 changed files with 11356 additions and 0 deletions
|
@ -133,12 +133,26 @@
|
|||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\arm\armemu.cpp" />
|
||||
<ClCompile Include="src\arm\arminit.cpp" />
|
||||
<ClCompile Include="src\arm\disassembler\arm_disasm.cpp" />
|
||||
<ClCompile Include="src\core.cpp" />
|
||||
<ClCompile Include="src\mem_map.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\arm\armcpu.h" />
|
||||
<ClInclude Include="src\arm\armdefs.h" />
|
||||
<ClInclude Include="src\arm\armemu.h" />
|
||||
<ClInclude Include="src\arm\armmmu.h" />
|
||||
<ClInclude Include="src\arm\armos.h" />
|
||||
<ClInclude Include="src\arm\arm_regformat.h" />
|
||||
<ClInclude Include="src\arm\disassembler\arm_disasm.h" />
|
||||
<ClInclude Include="src\arm\mmu\arm1176jzf_s_mmu.h" />
|
||||
<ClInclude Include="src\arm\mmu\cache.h" />
|
||||
<ClInclude Include="src\arm\mmu\rb.h" />
|
||||
<ClInclude Include="src\arm\mmu\tlb.h" />
|
||||
<ClInclude Include="src\arm\mmu\wb.h" />
|
||||
<ClInclude Include="src\arm\skyeye_defs.h" />
|
||||
<ClInclude Include="src\core.h" />
|
||||
<ClInclude Include="src\mem_map.h" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
<Filter>arm\disassembler</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\mem_map.cpp" />
|
||||
<ClCompile Include="src\arm\arminit.cpp">
|
||||
<Filter>arm</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\arm\armemu.cpp">
|
||||
<Filter>arm</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="arm">
|
||||
|
@ -14,6 +20,9 @@
|
|||
<Filter Include="arm\disassembler">
|
||||
<UniqueIdentifier>{61100188-a726-4024-ab16-95ee242b446e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="arm\mmu">
|
||||
<UniqueIdentifier>{a64d3c8a-747a-491b-b782-6e2622bedf24}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\arm\disassembler\arm_disasm.h">
|
||||
|
@ -21,5 +30,44 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="src\mem_map.h" />
|
||||
<ClInclude Include="src\core.h" />
|
||||
<ClInclude Include="src\arm\armdefs.h">
|
||||
<Filter>arm</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\arm\armemu.h">
|
||||
<Filter>arm</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\arm\skyeye_defs.h">
|
||||
<Filter>arm</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\arm\arm_regformat.h">
|
||||
<Filter>arm</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\arm\armos.h">
|
||||
<Filter>arm</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\arm\armmmu.h">
|
||||
<Filter>arm</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\arm\armcpu.h">
|
||||
<Filter>arm</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\arm\mmu\arm1176jzf_s_mmu.h">
|
||||
<Filter>arm\mmu</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\arm\mmu\cache.h">
|
||||
<Filter>arm\mmu</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\arm\mmu\rb.h">
|
||||
<Filter>arm\mmu</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\arm\mmu\tlb.h">
|
||||
<Filter>arm\mmu</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\arm\mmu\wb.h">
|
||||
<Filter>arm\mmu</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
103
src/core/src/arm/arm_regformat.h
Normal file
103
src/core/src/arm/arm_regformat.h
Normal file
|
@ -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
|
83
src/core/src/arm/armcpu.h
Normal file
83
src/core/src/arm/armcpu.h
Normal file
|
@ -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
|
||||
|
930
src/core/src/arm/armdefs.h
Normal file
930
src/core/src/arm/armdefs.h
Normal file
|
@ -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
Normal file
6618
src/core/src/arm/armemu.cpp
Normal file
File diff suppressed because it is too large
Load diff
657
src/core/src/arm/armemu.h
Normal file
657
src/core/src/arm/armemu.h
Normal 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
|
578
src/core/src/arm/arminit.cpp
Normal file
578
src/core/src/arm/arminit.cpp
Normal file
|
@ -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);
|
||||
//}
|
241
src/core/src/arm/armmmu.cpp
Normal file
241
src/core/src/arm/armmmu.cpp
Normal file
|
@ -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;
|
||||
}
|
254
src/core/src/arm/armmmu.h
Normal file
254
src/core/src/arm/armmmu.h
Normal file
|
@ -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_ */
|
138
src/core/src/arm/armos.h
Normal file
138
src/core/src/arm/armos.h
Normal file
|
@ -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
Normal file
1165
src/core/src/arm/mmu/arm1176jzf_s_mmu.c
Normal file
File diff suppressed because it is too large
Load diff
37
src/core/src/arm/mmu/arm1176jzf_s_mmu.h
Normal file
37
src/core/src/arm/mmu/arm1176jzf_s_mmu.h
Normal 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_*/
|
168
src/core/src/arm/mmu/cache.h
Normal file
168
src/core/src/arm/mmu/cache.h
Normal file
|
@ -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_*/
|
55
src/core/src/arm/mmu/rb.h
Normal file
55
src/core/src/arm/mmu/rb.h
Normal file
|
@ -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_*/
|
94
src/core/src/arm/mmu/tlb.h
Normal file
94
src/core/src/arm/mmu/tlb.h
Normal file
|
@ -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_*/
|
63
src/core/src/arm/mmu/wb.h
Normal file
63
src/core/src/arm/mmu/wb.h
Normal file
|
@ -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_*/
|
110
src/core/src/arm/skyeye_defs.h
Normal file
110
src/core/src/arm/skyeye_defs.h
Normal file
|
@ -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
|
Loading…
Reference in a new issue