ARM: Reorganized file structure to move shared SkyEye code to a more common area.
Removed s_ prefix
This commit is contained in:
parent
fd7f92d242
commit
b5e6524594
34 changed files with 80 additions and 80 deletions
103
src/core/arm/skyeye_common/arm_regformat.h
Normal file
103
src/core/arm/skyeye_common/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/arm/skyeye_common/armcpu.h
Normal file
83
src/core/arm/skyeye_common/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 "common/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
|
||||
|
931
src/core/arm/skyeye_common/armdefs.h
Normal file
931
src/core/arm/skyeye_common/armdefs.h
Normal file
|
@ -0,0 +1,931 @@
|
|||
/* 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>
|
||||
|
||||
#include "common/platform.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 "common/platform.h"
|
||||
#include "core/arm/skyeye_common/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
|
||||
|
||||
//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------
|
||||
#include <signal.h>
|
||||
|
||||
#include "common/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 "core/arm/skyeye_common/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 NumInstrsToExecute;
|
||||
|
||||
ARMword currentexaddr;
|
||||
ARMword currentexval;
|
||||
ARMword servaddr;
|
||||
|
||||
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_ */
|
656
src/core/arm/skyeye_common/armemu.h
Normal file
656
src/core/arm/skyeye_common/armemu.h
Normal file
|
@ -0,0 +1,656 @@
|
|||
/* 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 "core/arm/skyeye_common/armdefs.h"
|
||||
//#include "skyeye.h"
|
||||
|
||||
//extern ARMword isize;
|
||||
|
||||
#define DEBUG(...) DEBUG_LOG(ARM11, __VA_ARGS__)
|
||||
|
||||
/* 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
|
||||
#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] += INSN_SIZE; \
|
||||
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] += INSN_SIZE; \
|
||||
state->NextInstr |= 3; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define INCPC \
|
||||
do \
|
||||
{ \
|
||||
/* A standard PC inc. */ \
|
||||
state->Reg[15] += INSN_SIZE; \
|
||||
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) ) \
|
||||
|
||||
/* 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 WARN_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
|
254
src/core/arm/skyeye_common/armmmu.h
Normal file
254
src/core/arm/skyeye_common/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;\
|
||||
//})
|
||||
#define mmu_pid_va_map(va) ((va) & PID_VA_MAP_MASK) ? (va) : ((va) | (state->mmu.process_id & PID_VA_MAP_MASK))
|
||||
|
||||
/* 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 "core/arm/interpreter/mmu/tlb.h"
|
||||
#include "core/arm/interpreter/mmu/rb.h"
|
||||
#include "core/arm/interpreter/mmu/wb.h"
|
||||
#include "core/arm/interpreter/mmu/cache.h"
|
||||
|
||||
/*special process mmu.h*/
|
||||
#include "core/arm/interpreter/mmu/sa_mmu.h"
|
||||
//#include "core/arm/interpreter/mmu/arm7100_mmu.h"
|
||||
//#include "core/arm/interpreter/mmu/arm920t_mmu.h"
|
||||
//#include "core/arm/interpreter/mmu/arm926ejs_mmu.h"
|
||||
#include "core/arm/interpreter/mmu/arm1176jzf_s_mmu.h"
|
||||
//#include "core/arm/interpreter/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/arm/skyeye_common/armos.h
Normal file
138
src/core/arm/skyeye_common/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 */
|
||||
};
|
||||
|
111
src/core/arm/skyeye_common/skyeye_defs.h
Normal file
111
src/core/arm/skyeye_common/skyeye_defs.h
Normal file
|
@ -0,0 +1,111 @@
|
|||
#ifndef CORE_ARM_SKYEYE_DEFS_H_
|
||||
#define CORE_ARM_SKYEYE_DEFS_H_
|
||||
|
||||
#include "common/common.h"
|
||||
|
||||
#define MODE32
|
||||
#define MODET
|
||||
|
||||
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
|
84
src/core/arm/skyeye_common/vfp/asm_vfp.h
Normal file
84
src/core/arm/skyeye_common/vfp/asm_vfp.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* arch/arm/include/asm/vfp.h
|
||||
*
|
||||
* VFP register definitions.
|
||||
* First, the standard VFP set.
|
||||
*/
|
||||
|
||||
#define FPSID cr0
|
||||
#define FPSCR cr1
|
||||
#define MVFR1 cr6
|
||||
#define MVFR0 cr7
|
||||
#define FPEXC cr8
|
||||
#define FPINST cr9
|
||||
#define FPINST2 cr10
|
||||
|
||||
/* FPSID bits */
|
||||
#define FPSID_IMPLEMENTER_BIT (24)
|
||||
#define FPSID_IMPLEMENTER_MASK (0xff << FPSID_IMPLEMENTER_BIT)
|
||||
#define FPSID_SOFTWARE (1<<23)
|
||||
#define FPSID_FORMAT_BIT (21)
|
||||
#define FPSID_FORMAT_MASK (0x3 << FPSID_FORMAT_BIT)
|
||||
#define FPSID_NODOUBLE (1<<20)
|
||||
#define FPSID_ARCH_BIT (16)
|
||||
#define FPSID_ARCH_MASK (0xF << FPSID_ARCH_BIT)
|
||||
#define FPSID_PART_BIT (8)
|
||||
#define FPSID_PART_MASK (0xFF << FPSID_PART_BIT)
|
||||
#define FPSID_VARIANT_BIT (4)
|
||||
#define FPSID_VARIANT_MASK (0xF << FPSID_VARIANT_BIT)
|
||||
#define FPSID_REV_BIT (0)
|
||||
#define FPSID_REV_MASK (0xF << FPSID_REV_BIT)
|
||||
|
||||
/* FPEXC bits */
|
||||
#define FPEXC_EX (1 << 31)
|
||||
#define FPEXC_EN (1 << 30)
|
||||
#define FPEXC_DEX (1 << 29)
|
||||
#define FPEXC_FP2V (1 << 28)
|
||||
#define FPEXC_VV (1 << 27)
|
||||
#define FPEXC_TFV (1 << 26)
|
||||
#define FPEXC_LENGTH_BIT (8)
|
||||
#define FPEXC_LENGTH_MASK (7 << FPEXC_LENGTH_BIT)
|
||||
#define FPEXC_IDF (1 << 7)
|
||||
#define FPEXC_IXF (1 << 4)
|
||||
#define FPEXC_UFF (1 << 3)
|
||||
#define FPEXC_OFF (1 << 2)
|
||||
#define FPEXC_DZF (1 << 1)
|
||||
#define FPEXC_IOF (1 << 0)
|
||||
#define FPEXC_TRAP_MASK (FPEXC_IDF|FPEXC_IXF|FPEXC_UFF|FPEXC_OFF|FPEXC_DZF|FPEXC_IOF)
|
||||
|
||||
/* FPSCR bits */
|
||||
#define FPSCR_DEFAULT_NAN (1<<25)
|
||||
#define FPSCR_FLUSHTOZERO (1<<24)
|
||||
#define FPSCR_ROUND_NEAREST (0<<22)
|
||||
#define FPSCR_ROUND_PLUSINF (1<<22)
|
||||
#define FPSCR_ROUND_MINUSINF (2<<22)
|
||||
#define FPSCR_ROUND_TOZERO (3<<22)
|
||||
#define FPSCR_RMODE_BIT (22)
|
||||
#define FPSCR_RMODE_MASK (3 << FPSCR_RMODE_BIT)
|
||||
#define FPSCR_STRIDE_BIT (20)
|
||||
#define FPSCR_STRIDE_MASK (3 << FPSCR_STRIDE_BIT)
|
||||
#define FPSCR_LENGTH_BIT (16)
|
||||
#define FPSCR_LENGTH_MASK (7 << FPSCR_LENGTH_BIT)
|
||||
#define FPSCR_IOE (1<<8)
|
||||
#define FPSCR_DZE (1<<9)
|
||||
#define FPSCR_OFE (1<<10)
|
||||
#define FPSCR_UFE (1<<11)
|
||||
#define FPSCR_IXE (1<<12)
|
||||
#define FPSCR_IDE (1<<15)
|
||||
#define FPSCR_IOC (1<<0)
|
||||
#define FPSCR_DZC (1<<1)
|
||||
#define FPSCR_OFC (1<<2)
|
||||
#define FPSCR_UFC (1<<3)
|
||||
#define FPSCR_IXC (1<<4)
|
||||
#define FPSCR_IDC (1<<7)
|
||||
|
||||
/* MVFR0 bits */
|
||||
#define MVFR0_A_SIMD_BIT (0)
|
||||
#define MVFR0_A_SIMD_MASK (0xf << MVFR0_A_SIMD_BIT)
|
||||
|
||||
/* Bit patterns for decoding the packaged operation descriptors */
|
||||
#define VFPOPDESC_LENGTH_BIT (9)
|
||||
#define VFPOPDESC_LENGTH_MASK (0x07 << VFPOPDESC_LENGTH_BIT)
|
||||
#define VFPOPDESC_UNUSED_BIT (24)
|
||||
#define VFPOPDESC_UNUSED_MASK (0xFF << VFPOPDESC_UNUSED_BIT)
|
||||
#define VFPOPDESC_OPDESC_MASK (~(VFPOPDESC_LENGTH_MASK | VFPOPDESC_UNUSED_MASK))
|
357
src/core/arm/skyeye_common/vfp/vfp.cpp
Normal file
357
src/core/arm/skyeye_common/vfp/vfp.cpp
Normal file
|
@ -0,0 +1,357 @@
|
|||
/*
|
||||
armvfp.c - ARM VFPv3 emulation unit
|
||||
Copyright (C) 2003 Skyeye Develop Group
|
||||
for help please send mail to <skyeye-developer@lists.gro.clinux.org>
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
/* Note: this file handles interface with arm core and vfp registers */
|
||||
|
||||
/* Opens debug for classic interpreter only */
|
||||
//#define DEBUG
|
||||
|
||||
#include "common/common.h"
|
||||
|
||||
#include "core/arm/skyeye_common/armdefs.h"
|
||||
#include "core/arm/skyeye_common/vfp/vfp.h"
|
||||
|
||||
//ARMul_State* persistent_state; /* function calls from SoftFloat lib don't have an access to ARMul_state. */
|
||||
|
||||
unsigned
|
||||
VFPInit (ARMul_State *state)
|
||||
{
|
||||
state->VFP[VFP_OFFSET(VFP_FPSID)] = VFP_FPSID_IMPLMEN<<24 | VFP_FPSID_SW<<23 | VFP_FPSID_SUBARCH<<16 |
|
||||
VFP_FPSID_PARTNUM<<8 | VFP_FPSID_VARIANT<<4 | VFP_FPSID_REVISION;
|
||||
state->VFP[VFP_OFFSET(VFP_FPEXC)] = 0;
|
||||
state->VFP[VFP_OFFSET(VFP_FPSCR)] = 0;
|
||||
|
||||
//persistent_state = state;
|
||||
/* Reset only specify VFP_FPEXC_EN = '0' */
|
||||
|
||||
return No_exp;
|
||||
}
|
||||
|
||||
unsigned
|
||||
VFPMRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value)
|
||||
{
|
||||
/* MRC<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
|
||||
int CoProc = BITS (8, 11); /* 10 or 11 */
|
||||
int OPC_1 = BITS (21, 23);
|
||||
int Rt = BITS (12, 15);
|
||||
int CRn = BITS (16, 19);
|
||||
int CRm = BITS (0, 3);
|
||||
int OPC_2 = BITS (5, 7);
|
||||
|
||||
/* TODO check access permission */
|
||||
|
||||
/* CRn/opc1 CRm/opc2 */
|
||||
|
||||
if (CoProc == 10 || CoProc == 11)
|
||||
{
|
||||
#define VFP_MRC_TRANS
|
||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
||||
#undef VFP_MRC_TRANS
|
||||
}
|
||||
DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n",
|
||||
instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2);
|
||||
|
||||
return ARMul_CANT;
|
||||
}
|
||||
|
||||
unsigned
|
||||
VFPMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value)
|
||||
{
|
||||
/* MCR<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
|
||||
int CoProc = BITS (8, 11); /* 10 or 11 */
|
||||
int OPC_1 = BITS (21, 23);
|
||||
int Rt = BITS (12, 15);
|
||||
int CRn = BITS (16, 19);
|
||||
int CRm = BITS (0, 3);
|
||||
int OPC_2 = BITS (5, 7);
|
||||
|
||||
/* TODO check access permission */
|
||||
|
||||
/* CRn/opc1 CRm/opc2 */
|
||||
if (CoProc == 10 || CoProc == 11)
|
||||
{
|
||||
#define VFP_MCR_TRANS
|
||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
||||
#undef VFP_MCR_TRANS
|
||||
}
|
||||
DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n",
|
||||
instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2);
|
||||
|
||||
return ARMul_CANT;
|
||||
}
|
||||
|
||||
unsigned
|
||||
VFPMRRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value1, ARMword * value2)
|
||||
{
|
||||
/* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
|
||||
int CoProc = BITS (8, 11); /* 10 or 11 */
|
||||
int OPC_1 = BITS (4, 7);
|
||||
int Rt = BITS (12, 15);
|
||||
int Rt2 = BITS (16, 19);
|
||||
int CRm = BITS (0, 3);
|
||||
|
||||
if (CoProc == 10 || CoProc == 11)
|
||||
{
|
||||
#define VFP_MRRC_TRANS
|
||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
||||
#undef VFP_MRRC_TRANS
|
||||
}
|
||||
DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",
|
||||
instr, CoProc, OPC_1, Rt, Rt2, CRm);
|
||||
|
||||
return ARMul_CANT;
|
||||
}
|
||||
|
||||
unsigned
|
||||
VFPMCRR (ARMul_State * state, unsigned type, ARMword instr, ARMword value1, ARMword value2)
|
||||
{
|
||||
/* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
|
||||
int CoProc = BITS (8, 11); /* 10 or 11 */
|
||||
int OPC_1 = BITS (4, 7);
|
||||
int Rt = BITS (12, 15);
|
||||
int Rt2 = BITS (16, 19);
|
||||
int CRm = BITS (0, 3);
|
||||
|
||||
/* TODO check access permission */
|
||||
|
||||
/* CRn/opc1 CRm/opc2 */
|
||||
|
||||
if (CoProc == 11 || CoProc == 10)
|
||||
{
|
||||
#define VFP_MCRR_TRANS
|
||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
||||
#undef VFP_MCRR_TRANS
|
||||
}
|
||||
DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",
|
||||
instr, CoProc, OPC_1, Rt, Rt2, CRm);
|
||||
|
||||
return ARMul_CANT;
|
||||
}
|
||||
|
||||
unsigned
|
||||
VFPSTC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value)
|
||||
{
|
||||
/* STC{L}<c> <coproc>,<CRd>,[<Rn>],<option> */
|
||||
int CoProc = BITS (8, 11); /* 10 or 11 */
|
||||
int CRd = BITS (12, 15);
|
||||
int Rn = BITS (16, 19);
|
||||
int imm8 = BITS (0, 7);
|
||||
int P = BIT(24);
|
||||
int U = BIT(23);
|
||||
int D = BIT(22);
|
||||
int W = BIT(21);
|
||||
|
||||
/* TODO check access permission */
|
||||
|
||||
/* VSTM */
|
||||
if ( (P|U|D|W) == 0 )
|
||||
{
|
||||
DEBUG_LOG(ARM11, "In %s, UNDEFINED\n", __FUNCTION__); exit(-1);
|
||||
}
|
||||
if (CoProc == 10 || CoProc == 11)
|
||||
{
|
||||
#if 1
|
||||
if (P == 0 && U == 0 && W == 0)
|
||||
{
|
||||
DEBUG_LOG(ARM11, "VSTM Related encodings\n"); exit(-1);
|
||||
}
|
||||
if (P == U && W == 1)
|
||||
{
|
||||
DEBUG_LOG(ARM11, "UNDEFINED\n"); exit(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define VFP_STC_TRANS
|
||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
||||
#undef VFP_STC_TRANS
|
||||
}
|
||||
DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n",
|
||||
instr, CoProc, CRd, Rn, imm8, P, U, D, W);
|
||||
|
||||
return ARMul_CANT;
|
||||
}
|
||||
|
||||
unsigned
|
||||
VFPLDC (ARMul_State * state, unsigned type, ARMword instr, ARMword value)
|
||||
{
|
||||
/* LDC{L}<c> <coproc>,<CRd>,[<Rn>] */
|
||||
int CoProc = BITS (8, 11); /* 10 or 11 */
|
||||
int CRd = BITS (12, 15);
|
||||
int Rn = BITS (16, 19);
|
||||
int imm8 = BITS (0, 7);
|
||||
int P = BIT(24);
|
||||
int U = BIT(23);
|
||||
int D = BIT(22);
|
||||
int W = BIT(21);
|
||||
|
||||
/* TODO check access permission */
|
||||
|
||||
if ( (P|U|D|W) == 0 )
|
||||
{
|
||||
DEBUG_LOG(ARM11, "In %s, UNDEFINED\n", __FUNCTION__); exit(-1);
|
||||
}
|
||||
if (CoProc == 10 || CoProc == 11)
|
||||
{
|
||||
#define VFP_LDC_TRANS
|
||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
||||
#undef VFP_LDC_TRANS
|
||||
}
|
||||
DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n",
|
||||
instr, CoProc, CRd, Rn, imm8, P, U, D, W);
|
||||
|
||||
return ARMul_CANT;
|
||||
}
|
||||
|
||||
unsigned
|
||||
VFPCDP (ARMul_State * state, unsigned type, ARMword instr)
|
||||
{
|
||||
/* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */
|
||||
int CoProc = BITS (8, 11); /* 10 or 11 */
|
||||
int OPC_1 = BITS (20, 23);
|
||||
int CRd = BITS (12, 15);
|
||||
int CRn = BITS (16, 19);
|
||||
int CRm = BITS (0, 3);
|
||||
int OPC_2 = BITS (5, 7);
|
||||
|
||||
/* TODO check access permission */
|
||||
|
||||
/* CRn/opc1 CRm/opc2 */
|
||||
|
||||
if (CoProc == 10 || CoProc == 11)
|
||||
{
|
||||
#define VFP_CDP_TRANS
|
||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
||||
#undef VFP_CDP_TRANS
|
||||
|
||||
int exceptions = 0;
|
||||
if (CoProc == 10)
|
||||
exceptions = vfp_single_cpdo(state, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]);
|
||||
else
|
||||
exceptions = vfp_double_cpdo(state, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]);
|
||||
|
||||
vfp_raise_exceptions(state, exceptions, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]);
|
||||
|
||||
return ARMul_DONE;
|
||||
}
|
||||
DEBUG_LOG(ARM11, "Can't identify %x\n", instr);
|
||||
return ARMul_CANT;
|
||||
}
|
||||
|
||||
|
||||
/* ----------- MRC ------------ */
|
||||
#define VFP_MRC_IMPL
|
||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
||||
#undef VFP_MRC_IMPL
|
||||
|
||||
#define VFP_MRRC_IMPL
|
||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
||||
#undef VFP_MRRC_IMPL
|
||||
|
||||
|
||||
/* ----------- MCR ------------ */
|
||||
#define VFP_MCR_IMPL
|
||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
||||
#undef VFP_MCR_IMPL
|
||||
|
||||
#define VFP_MCRR_IMPL
|
||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
||||
#undef VFP_MCRR_IMPL
|
||||
|
||||
/* Memory operation are not inlined, as old Interpreter and Fast interpreter
|
||||
don't have the same memory operation interface.
|
||||
Old interpreter framework does one access to coprocessor per data, and
|
||||
handles already data write, as well as address computation,
|
||||
which is not the case for Fast interpreter. Therefore, implementation
|
||||
of vfp instructions in old interpreter and fast interpreter are separate. */
|
||||
|
||||
/* ----------- STC ------------ */
|
||||
#define VFP_STC_IMPL
|
||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
||||
#undef VFP_STC_IMPL
|
||||
|
||||
|
||||
/* ----------- LDC ------------ */
|
||||
#define VFP_LDC_IMPL
|
||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
||||
#undef VFP_LDC_IMPL
|
||||
|
||||
|
||||
/* ----------- CDP ------------ */
|
||||
#define VFP_CDP_IMPL
|
||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
||||
#undef VFP_CDP_IMPL
|
||||
|
||||
/* Miscellaneous functions */
|
||||
int32_t vfp_get_float(arm_core_t* state, unsigned int reg)
|
||||
{
|
||||
DBG("VFP get float: s%d=[%08x]\n", reg, state->ExtReg[reg]);
|
||||
return state->ExtReg[reg];
|
||||
}
|
||||
|
||||
void vfp_put_float(arm_core_t* state, int32_t val, unsigned int reg)
|
||||
{
|
||||
DBG("VFP put float: s%d <= [%08x]\n", reg, val);
|
||||
state->ExtReg[reg] = val;
|
||||
}
|
||||
|
||||
uint64_t vfp_get_double(arm_core_t* state, unsigned int reg)
|
||||
{
|
||||
uint64_t result;
|
||||
result = ((uint64_t) state->ExtReg[reg*2+1])<<32 | state->ExtReg[reg*2];
|
||||
DBG("VFP get double: s[%d-%d]=[%016llx]\n", reg*2+1, reg*2, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void vfp_put_double(arm_core_t* state, uint64_t val, unsigned int reg)
|
||||
{
|
||||
DBG("VFP put double: s[%d-%d] <= [%08x-%08x]\n", reg*2+1, reg*2, (uint32_t) (val>>32), (uint32_t) (val & 0xffffffff));
|
||||
state->ExtReg[reg*2] = (uint32_t) (val & 0xffffffff);
|
||||
state->ExtReg[reg*2+1] = (uint32_t) (val>>32);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Process bitmask of exception conditions. (from vfpmodule.c)
|
||||
*/
|
||||
void vfp_raise_exceptions(ARMul_State* state, u32 exceptions, u32 inst, u32 fpscr)
|
||||
{
|
||||
int si_code = 0;
|
||||
|
||||
vfpdebug("VFP: raising exceptions %08x\n", exceptions);
|
||||
|
||||
if (exceptions == VFP_EXCEPTION_ERROR) {
|
||||
DEBUG_LOG(ARM11, "unhandled bounce %x\n", inst);
|
||||
exit(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If any of the status flags are set, update the FPSCR.
|
||||
* Comparison instructions always return at least one of
|
||||
* these flags set.
|
||||
*/
|
||||
if (exceptions & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V))
|
||||
fpscr &= ~(FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V);
|
||||
|
||||
fpscr |= exceptions;
|
||||
|
||||
state->VFP[VFP_OFFSET(VFP_FPSCR)] = fpscr;
|
||||
}
|
111
src/core/arm/skyeye_common/vfp/vfp.h
Normal file
111
src/core/arm/skyeye_common/vfp/vfp.h
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
vfp/vfp.h - ARM VFPv3 emulation unit - vfp interface
|
||||
Copyright (C) 2003 Skyeye Develop Group
|
||||
for help please send mail to <skyeye-developer@lists.gro.clinux.org>
|
||||
|
||||
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 __VFP_H__
|
||||
#define __VFP_H__
|
||||
|
||||
#define DBG(...) //DEBUG_LOG(ARM11, __VA_ARGS__)
|
||||
|
||||
#define vfpdebug //printf
|
||||
|
||||
#include "core/arm/skyeye_common/vfp/vfp_helper.h" /* for references to cdp SoftFloat functions */
|
||||
|
||||
unsigned VFPInit (ARMul_State *state);
|
||||
unsigned VFPMRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value);
|
||||
unsigned VFPMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value);
|
||||
unsigned VFPMRRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value1, ARMword * value2);
|
||||
unsigned VFPMCRR (ARMul_State * state, unsigned type, ARMword instr, ARMword value1, ARMword value2);
|
||||
unsigned VFPSTC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value);
|
||||
unsigned VFPLDC (ARMul_State * state, unsigned type, ARMword instr, ARMword value);
|
||||
unsigned VFPCDP (ARMul_State * state, unsigned type, ARMword instr);
|
||||
|
||||
/* FPSID Information */
|
||||
#define VFP_FPSID_IMPLMEN 0 /* should be the same as cp15 0 c0 0*/
|
||||
#define VFP_FPSID_SW 0
|
||||
#define VFP_FPSID_SUBARCH 0x2 /* VFP version. Current is v3 (not strict) */
|
||||
#define VFP_FPSID_PARTNUM 0x1
|
||||
#define VFP_FPSID_VARIANT 0x1
|
||||
#define VFP_FPSID_REVISION 0x1
|
||||
|
||||
/* FPEXC Flags */
|
||||
#define VFP_FPEXC_EX 1<<31
|
||||
#define VFP_FPEXC_EN 1<<30
|
||||
|
||||
/* FPSCR Flags */
|
||||
#define VFP_FPSCR_NFLAG 1<<31
|
||||
#define VFP_FPSCR_ZFLAG 1<<30
|
||||
#define VFP_FPSCR_CFLAG 1<<29
|
||||
#define VFP_FPSCR_VFLAG 1<<28
|
||||
|
||||
#define VFP_FPSCR_AHP 1<<26 /* Alternative Half Precision */
|
||||
#define VFP_FPSCR_DN 1<<25 /* Default NaN */
|
||||
#define VFP_FPSCR_FZ 1<<24 /* Flush-to-zero */
|
||||
#define VFP_FPSCR_RMODE 3<<22 /* Rounding Mode */
|
||||
#define VFP_FPSCR_STRIDE 3<<20 /* Stride (vector) */
|
||||
#define VFP_FPSCR_LEN 7<<16 /* Stride (vector) */
|
||||
|
||||
#define VFP_FPSCR_IDE 1<<15 /* Input Denormal exc */
|
||||
#define VFP_FPSCR_IXE 1<<12 /* Inexact exc */
|
||||
#define VFP_FPSCR_UFE 1<<11 /* Undeflow exc */
|
||||
#define VFP_FPSCR_OFE 1<<10 /* Overflow exc */
|
||||
#define VFP_FPSCR_DZE 1<<9 /* Division by Zero exc */
|
||||
#define VFP_FPSCR_IOE 1<<8 /* Invalid Operation exc */
|
||||
|
||||
#define VFP_FPSCR_IDC 1<<7 /* Input Denormal cum exc */
|
||||
#define VFP_FPSCR_IXC 1<<4 /* Inexact cum exc */
|
||||
#define VFP_FPSCR_UFC 1<<3 /* Undeflow cum exc */
|
||||
#define VFP_FPSCR_OFC 1<<2 /* Overflow cum exc */
|
||||
#define VFP_FPSCR_DZC 1<<1 /* Division by Zero cum exc */
|
||||
#define VFP_FPSCR_IOC 1<<0 /* Invalid Operation cum exc */
|
||||
|
||||
/* Inline instructions. Note: Used in a cpp file as well */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int32_t vfp_get_float(ARMul_State * state, unsigned int reg);
|
||||
void vfp_put_float(ARMul_State * state, int32_t val, unsigned int reg);
|
||||
uint64_t vfp_get_double(ARMul_State * state, unsigned int reg);
|
||||
void vfp_put_double(ARMul_State * state, uint64_t val, unsigned int reg);
|
||||
void vfp_raise_exceptions(ARMul_State * state, uint32_t exceptions, uint32_t inst, uint32_t fpscr);
|
||||
u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr);
|
||||
u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr);
|
||||
|
||||
/* MRC */
|
||||
inline void VMRS(ARMul_State * state, ARMword reg, ARMword Rt, ARMword *value);
|
||||
inline void VMOVBRS(ARMul_State * state, ARMword to_arm, ARMword t, ARMword n, ARMword *value);
|
||||
inline void VMOVBRRD(ARMul_State * state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword *value1, ARMword *value2);
|
||||
inline void VMOVI(ARMul_State * state, ARMword single, ARMword d, ARMword imm);
|
||||
inline void VMOVR(ARMul_State * state, ARMword single, ARMword d, ARMword imm);
|
||||
/* MCR */
|
||||
inline void VMSR(ARMul_State * state, ARMword reg, ARMword Rt);
|
||||
/* STC */
|
||||
inline int VSTM(ARMul_State * state, int type, ARMword instr, ARMword* value);
|
||||
inline int VPUSH(ARMul_State * state, int type, ARMword instr, ARMword* value);
|
||||
inline int VSTR(ARMul_State * state, int type, ARMword instr, ARMword* value);
|
||||
/* LDC */
|
||||
inline int VLDM(ARMul_State * state, int type, ARMword instr, ARMword value);
|
||||
inline int VPOP(ARMul_State * state, int type, ARMword instr, ARMword value);
|
||||
inline int VLDR(ARMul_State * state, int type, ARMword instr, ARMword value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
541
src/core/arm/skyeye_common/vfp/vfp_helper.h
Normal file
541
src/core/arm/skyeye_common/vfp/vfp_helper.h
Normal file
|
@ -0,0 +1,541 @@
|
|||
/*
|
||||
vfp/vfp.h - ARM VFPv3 emulation unit - SoftFloat lib helper
|
||||
Copyright (C) 2003 Skyeye Develop Group
|
||||
for help please send mail to <skyeye-developer@lists.gro.clinux.org>
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following code is derivative from Linux Android kernel vfp
|
||||
* floating point support.
|
||||
*
|
||||
* Copyright (C) 2004 ARM Limited.
|
||||
* Written by Deep Blue Solutions Limited.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __VFP_HELPER_H__
|
||||
#define __VFP_HELPER_H__
|
||||
|
||||
/* Custom edit */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "core/arm/skyeye_common/armdefs.h"
|
||||
|
||||
#define u16 uint16_t
|
||||
#define u32 uint32_t
|
||||
#define u64 uint64_t
|
||||
#define s16 int16_t
|
||||
#define s32 int32_t
|
||||
#define s64 int64_t
|
||||
|
||||
#define pr_info //printf
|
||||
#define pr_debug //printf
|
||||
|
||||
static u32 vfp_fls(int x);
|
||||
#define do_div(n, base) {n/=base;}
|
||||
|
||||
/* From vfpinstr.h */
|
||||
|
||||
#define INST_CPRTDO(inst) (((inst) & 0x0f000000) == 0x0e000000)
|
||||
#define INST_CPRT(inst) ((inst) & (1 << 4))
|
||||
#define INST_CPRT_L(inst) ((inst) & (1 << 20))
|
||||
#define INST_CPRT_Rd(inst) (((inst) & (15 << 12)) >> 12)
|
||||
#define INST_CPRT_OP(inst) (((inst) >> 21) & 7)
|
||||
#define INST_CPNUM(inst) ((inst) & 0xf00)
|
||||
#define CPNUM(cp) ((cp) << 8)
|
||||
|
||||
#define FOP_MASK (0x00b00040)
|
||||
#define FOP_FMAC (0x00000000)
|
||||
#define FOP_FNMAC (0x00000040)
|
||||
#define FOP_FMSC (0x00100000)
|
||||
#define FOP_FNMSC (0x00100040)
|
||||
#define FOP_FMUL (0x00200000)
|
||||
#define FOP_FNMUL (0x00200040)
|
||||
#define FOP_FADD (0x00300000)
|
||||
#define FOP_FSUB (0x00300040)
|
||||
#define FOP_FDIV (0x00800000)
|
||||
#define FOP_EXT (0x00b00040)
|
||||
|
||||
#define FOP_TO_IDX(inst) ((inst & 0x00b00000) >> 20 | (inst & (1 << 6)) >> 4)
|
||||
|
||||
#define FEXT_MASK (0x000f0080)
|
||||
#define FEXT_FCPY (0x00000000)
|
||||
#define FEXT_FABS (0x00000080)
|
||||
#define FEXT_FNEG (0x00010000)
|
||||
#define FEXT_FSQRT (0x00010080)
|
||||
#define FEXT_FCMP (0x00040000)
|
||||
#define FEXT_FCMPE (0x00040080)
|
||||
#define FEXT_FCMPZ (0x00050000)
|
||||
#define FEXT_FCMPEZ (0x00050080)
|
||||
#define FEXT_FCVT (0x00070080)
|
||||
#define FEXT_FUITO (0x00080000)
|
||||
#define FEXT_FSITO (0x00080080)
|
||||
#define FEXT_FTOUI (0x000c0000)
|
||||
#define FEXT_FTOUIZ (0x000c0080)
|
||||
#define FEXT_FTOSI (0x000d0000)
|
||||
#define FEXT_FTOSIZ (0x000d0080)
|
||||
|
||||
#define FEXT_TO_IDX(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7)
|
||||
|
||||
#define vfp_get_sd(inst) ((inst & 0x0000f000) >> 11 | (inst & (1 << 22)) >> 22)
|
||||
#define vfp_get_dd(inst) ((inst & 0x0000f000) >> 12 | (inst & (1 << 22)) >> 18)
|
||||
#define vfp_get_sm(inst) ((inst & 0x0000000f) << 1 | (inst & (1 << 5)) >> 5)
|
||||
#define vfp_get_dm(inst) ((inst & 0x0000000f) | (inst & (1 << 5)) >> 1)
|
||||
#define vfp_get_sn(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7)
|
||||
#define vfp_get_dn(inst) ((inst & 0x000f0000) >> 16 | (inst & (1 << 7)) >> 3)
|
||||
|
||||
#define vfp_single(inst) (((inst) & 0x0000f00) == 0xa00)
|
||||
|
||||
#define FPSCR_N (1 << 31)
|
||||
#define FPSCR_Z (1 << 30)
|
||||
#define FPSCR_C (1 << 29)
|
||||
#define FPSCR_V (1 << 28)
|
||||
|
||||
/* -------------- */
|
||||
|
||||
/* From asm/include/vfp.h */
|
||||
|
||||
/* FPSCR bits */
|
||||
#define FPSCR_DEFAULT_NAN (1<<25)
|
||||
#define FPSCR_FLUSHTOZERO (1<<24)
|
||||
#define FPSCR_ROUND_NEAREST (0<<22)
|
||||
#define FPSCR_ROUND_PLUSINF (1<<22)
|
||||
#define FPSCR_ROUND_MINUSINF (2<<22)
|
||||
#define FPSCR_ROUND_TOZERO (3<<22)
|
||||
#define FPSCR_RMODE_BIT (22)
|
||||
#define FPSCR_RMODE_MASK (3 << FPSCR_RMODE_BIT)
|
||||
#define FPSCR_STRIDE_BIT (20)
|
||||
#define FPSCR_STRIDE_MASK (3 << FPSCR_STRIDE_BIT)
|
||||
#define FPSCR_LENGTH_BIT (16)
|
||||
#define FPSCR_LENGTH_MASK (7 << FPSCR_LENGTH_BIT)
|
||||
#define FPSCR_IOE (1<<8)
|
||||
#define FPSCR_DZE (1<<9)
|
||||
#define FPSCR_OFE (1<<10)
|
||||
#define FPSCR_UFE (1<<11)
|
||||
#define FPSCR_IXE (1<<12)
|
||||
#define FPSCR_IDE (1<<15)
|
||||
#define FPSCR_IOC (1<<0)
|
||||
#define FPSCR_DZC (1<<1)
|
||||
#define FPSCR_OFC (1<<2)
|
||||
#define FPSCR_UFC (1<<3)
|
||||
#define FPSCR_IXC (1<<4)
|
||||
#define FPSCR_IDC (1<<7)
|
||||
|
||||
/* ---------------- */
|
||||
|
||||
static inline u32 vfp_shiftright32jamming(u32 val, unsigned int shift)
|
||||
{
|
||||
if (shift) {
|
||||
if (shift < 32)
|
||||
val = val >> shift | ((val << (32 - shift)) != 0);
|
||||
else
|
||||
val = val != 0;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline u64 vfp_shiftright64jamming(u64 val, unsigned int shift)
|
||||
{
|
||||
if (shift) {
|
||||
if (shift < 64)
|
||||
val = val >> shift | ((val << (64 - shift)) != 0);
|
||||
else
|
||||
val = val != 0;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline u32 vfp_hi64to32jamming(u64 val)
|
||||
{
|
||||
u32 v;
|
||||
u32 highval = val >> 32;
|
||||
u32 lowval = val & 0xffffffff;
|
||||
|
||||
if (lowval >= 1)
|
||||
v = highval | 1;
|
||||
else
|
||||
v = highval;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline void add128(u64 *resh, u64 *resl, u64 nh, u64 nl, u64 mh, u64 ml)
|
||||
{
|
||||
*resl = nl + ml;
|
||||
*resh = nh + mh;
|
||||
if (*resl < nl)
|
||||
*resh += 1;
|
||||
}
|
||||
|
||||
static inline void sub128(u64 *resh, u64 *resl, u64 nh, u64 nl, u64 mh, u64 ml)
|
||||
{
|
||||
*resl = nl - ml;
|
||||
*resh = nh - mh;
|
||||
if (*resl > nl)
|
||||
*resh -= 1;
|
||||
}
|
||||
|
||||
static inline void mul64to128(u64 *resh, u64 *resl, u64 n, u64 m)
|
||||
{
|
||||
u32 nh, nl, mh, ml;
|
||||
u64 rh, rma, rmb, rl;
|
||||
|
||||
nl = n;
|
||||
ml = m;
|
||||
rl = (u64)nl * ml;
|
||||
|
||||
nh = n >> 32;
|
||||
rma = (u64)nh * ml;
|
||||
|
||||
mh = m >> 32;
|
||||
rmb = (u64)nl * mh;
|
||||
rma += rmb;
|
||||
|
||||
rh = (u64)nh * mh;
|
||||
rh += ((u64)(rma < rmb) << 32) + (rma >> 32);
|
||||
|
||||
rma <<= 32;
|
||||
rl += rma;
|
||||
rh += (rl < rma);
|
||||
|
||||
*resl = rl;
|
||||
*resh = rh;
|
||||
}
|
||||
|
||||
static inline void shift64left(u64 *resh, u64 *resl, u64 n)
|
||||
{
|
||||
*resh = n >> 63;
|
||||
*resl = n << 1;
|
||||
}
|
||||
|
||||
static inline u64 vfp_hi64multiply64(u64 n, u64 m)
|
||||
{
|
||||
u64 rh, rl;
|
||||
mul64to128(&rh, &rl, n, m);
|
||||
return rh | (rl != 0);
|
||||
}
|
||||
|
||||
static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m)
|
||||
{
|
||||
u64 mh, ml, remh, reml, termh, terml, z;
|
||||
|
||||
if (nh >= m)
|
||||
return ~0ULL;
|
||||
mh = m >> 32;
|
||||
if (mh << 32 <= nh) {
|
||||
z = 0xffffffff00000000ULL;
|
||||
} else {
|
||||
z = nh;
|
||||
do_div(z, mh);
|
||||
z <<= 32;
|
||||
}
|
||||
mul64to128(&termh, &terml, m, z);
|
||||
sub128(&remh, &reml, nh, nl, termh, terml);
|
||||
ml = m << 32;
|
||||
while ((s64)remh < 0) {
|
||||
z -= 0x100000000ULL;
|
||||
add128(&remh, &reml, remh, reml, mh, ml);
|
||||
}
|
||||
remh = (remh << 32) | (reml >> 32);
|
||||
if (mh << 32 <= remh) {
|
||||
z |= 0xffffffff;
|
||||
} else {
|
||||
do_div(remh, mh);
|
||||
z |= remh;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
/*
|
||||
* Operations on unpacked elements
|
||||
*/
|
||||
#define vfp_sign_negate(sign) (sign ^ 0x8000)
|
||||
|
||||
/*
|
||||
* Single-precision
|
||||
*/
|
||||
struct vfp_single {
|
||||
s16 exponent;
|
||||
u16 sign;
|
||||
u32 significand;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern s32 vfp_get_float(ARMul_State * state, unsigned int reg);
|
||||
extern void vfp_put_float(ARMul_State * state, s32 val, unsigned int reg);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* VFP_SINGLE_MANTISSA_BITS - number of bits in the mantissa
|
||||
* VFP_SINGLE_EXPONENT_BITS - number of bits in the exponent
|
||||
* VFP_SINGLE_LOW_BITS - number of low bits in the unpacked significand
|
||||
* which are not propagated to the float upon packing.
|
||||
*/
|
||||
#define VFP_SINGLE_MANTISSA_BITS (23)
|
||||
#define VFP_SINGLE_EXPONENT_BITS (8)
|
||||
#define VFP_SINGLE_LOW_BITS (32 - VFP_SINGLE_MANTISSA_BITS - 2)
|
||||
#define VFP_SINGLE_LOW_BITS_MASK ((1 << VFP_SINGLE_LOW_BITS) - 1)
|
||||
|
||||
/*
|
||||
* The bit in an unpacked float which indicates that it is a quiet NaN
|
||||
*/
|
||||
#define VFP_SINGLE_SIGNIFICAND_QNAN (1 << (VFP_SINGLE_MANTISSA_BITS - 1 + VFP_SINGLE_LOW_BITS))
|
||||
|
||||
/*
|
||||
* Operations on packed single-precision numbers
|
||||
*/
|
||||
#define vfp_single_packed_sign(v) ((v) & 0x80000000)
|
||||
#define vfp_single_packed_negate(v) ((v) ^ 0x80000000)
|
||||
#define vfp_single_packed_abs(v) ((v) & ~0x80000000)
|
||||
#define vfp_single_packed_exponent(v) (((v) >> VFP_SINGLE_MANTISSA_BITS) & ((1 << VFP_SINGLE_EXPONENT_BITS) - 1))
|
||||
#define vfp_single_packed_mantissa(v) ((v) & ((1 << VFP_SINGLE_MANTISSA_BITS) - 1))
|
||||
|
||||
/*
|
||||
* Unpack a single-precision float. Note that this returns the magnitude
|
||||
* of the single-precision float mantissa with the 1. if necessary,
|
||||
* aligned to bit 30.
|
||||
*/
|
||||
static inline void vfp_single_unpack(struct vfp_single *s, s32 val)
|
||||
{
|
||||
u32 significand;
|
||||
|
||||
s->sign = vfp_single_packed_sign(val) >> 16,
|
||||
s->exponent = vfp_single_packed_exponent(val);
|
||||
|
||||
significand = (u32) val;
|
||||
significand = (significand << (32 - VFP_SINGLE_MANTISSA_BITS)) >> 2;
|
||||
if (s->exponent && s->exponent != 255)
|
||||
significand |= 0x40000000;
|
||||
s->significand = significand;
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-pack a single-precision float. This assumes that the float is
|
||||
* already normalised such that the MSB is bit 30, _not_ bit 31.
|
||||
*/
|
||||
static inline s32 vfp_single_pack(struct vfp_single *s)
|
||||
{
|
||||
u32 val;
|
||||
val = (s->sign << 16) +
|
||||
(s->exponent << VFP_SINGLE_MANTISSA_BITS) +
|
||||
(s->significand >> VFP_SINGLE_LOW_BITS);
|
||||
return (s32)val;
|
||||
}
|
||||
|
||||
#define VFP_NUMBER (1<<0)
|
||||
#define VFP_ZERO (1<<1)
|
||||
#define VFP_DENORMAL (1<<2)
|
||||
#define VFP_INFINITY (1<<3)
|
||||
#define VFP_NAN (1<<4)
|
||||
#define VFP_NAN_SIGNAL (1<<5)
|
||||
|
||||
#define VFP_QNAN (VFP_NAN)
|
||||
#define VFP_SNAN (VFP_NAN|VFP_NAN_SIGNAL)
|
||||
|
||||
static inline int vfp_single_type(struct vfp_single *s)
|
||||
{
|
||||
int type = VFP_NUMBER;
|
||||
if (s->exponent == 255) {
|
||||
if (s->significand == 0)
|
||||
type = VFP_INFINITY;
|
||||
else if (s->significand & VFP_SINGLE_SIGNIFICAND_QNAN)
|
||||
type = VFP_QNAN;
|
||||
else
|
||||
type = VFP_SNAN;
|
||||
} else if (s->exponent == 0) {
|
||||
if (s->significand == 0)
|
||||
type |= VFP_ZERO;
|
||||
else
|
||||
type |= VFP_DENORMAL;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
u32 vfp_single_normaliseround(ARMul_State* state, int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions, const char *func);
|
||||
|
||||
/*
|
||||
* Double-precision
|
||||
*/
|
||||
struct vfp_double {
|
||||
s16 exponent;
|
||||
u16 sign;
|
||||
u64 significand;
|
||||
};
|
||||
|
||||
/*
|
||||
* VFP_REG_ZERO is a special register number for vfp_get_double
|
||||
* which returns (double)0.0. This is useful for the compare with
|
||||
* zero instructions.
|
||||
*/
|
||||
#ifdef CONFIG_VFPv3
|
||||
#define VFP_REG_ZERO 32
|
||||
#else
|
||||
#define VFP_REG_ZERO 16
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern u64 vfp_get_double(ARMul_State * state, unsigned int reg);
|
||||
extern void vfp_put_double(ARMul_State * state, u64 val, unsigned int reg);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#define VFP_DOUBLE_MANTISSA_BITS (52)
|
||||
#define VFP_DOUBLE_EXPONENT_BITS (11)
|
||||
#define VFP_DOUBLE_LOW_BITS (64 - VFP_DOUBLE_MANTISSA_BITS - 2)
|
||||
#define VFP_DOUBLE_LOW_BITS_MASK ((1 << VFP_DOUBLE_LOW_BITS) - 1)
|
||||
|
||||
/*
|
||||
* The bit in an unpacked double which indicates that it is a quiet NaN
|
||||
*/
|
||||
#define VFP_DOUBLE_SIGNIFICAND_QNAN (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1 + VFP_DOUBLE_LOW_BITS))
|
||||
|
||||
/*
|
||||
* Operations on packed single-precision numbers
|
||||
*/
|
||||
#define vfp_double_packed_sign(v) ((v) & (1ULL << 63))
|
||||
#define vfp_double_packed_negate(v) ((v) ^ (1ULL << 63))
|
||||
#define vfp_double_packed_abs(v) ((v) & ~(1ULL << 63))
|
||||
#define vfp_double_packed_exponent(v) (((v) >> VFP_DOUBLE_MANTISSA_BITS) & ((1 << VFP_DOUBLE_EXPONENT_BITS) - 1))
|
||||
#define vfp_double_packed_mantissa(v) ((v) & ((1ULL << VFP_DOUBLE_MANTISSA_BITS) - 1))
|
||||
|
||||
/*
|
||||
* Unpack a double-precision float. Note that this returns the magnitude
|
||||
* of the double-precision float mantissa with the 1. if necessary,
|
||||
* aligned to bit 62.
|
||||
*/
|
||||
static inline void vfp_double_unpack(struct vfp_double *s, s64 val)
|
||||
{
|
||||
u64 significand;
|
||||
|
||||
s->sign = vfp_double_packed_sign(val) >> 48;
|
||||
s->exponent = vfp_double_packed_exponent(val);
|
||||
|
||||
significand = (u64) val;
|
||||
significand = (significand << (64 - VFP_DOUBLE_MANTISSA_BITS)) >> 2;
|
||||
if (s->exponent && s->exponent != 2047)
|
||||
significand |= (1ULL << 62);
|
||||
s->significand = significand;
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-pack a double-precision float. This assumes that the float is
|
||||
* already normalised such that the MSB is bit 30, _not_ bit 31.
|
||||
*/
|
||||
static inline s64 vfp_double_pack(struct vfp_double *s)
|
||||
{
|
||||
u64 val;
|
||||
val = ((u64)s->sign << 48) +
|
||||
((u64)s->exponent << VFP_DOUBLE_MANTISSA_BITS) +
|
||||
(s->significand >> VFP_DOUBLE_LOW_BITS);
|
||||
return (s64)val;
|
||||
}
|
||||
|
||||
static inline int vfp_double_type(struct vfp_double *s)
|
||||
{
|
||||
int type = VFP_NUMBER;
|
||||
if (s->exponent == 2047) {
|
||||
if (s->significand == 0)
|
||||
type = VFP_INFINITY;
|
||||
else if (s->significand & VFP_DOUBLE_SIGNIFICAND_QNAN)
|
||||
type = VFP_QNAN;
|
||||
else
|
||||
type = VFP_SNAN;
|
||||
} else if (s->exponent == 0) {
|
||||
if (s->significand == 0)
|
||||
type |= VFP_ZERO;
|
||||
else
|
||||
type |= VFP_DENORMAL;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func);
|
||||
|
||||
u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand);
|
||||
|
||||
/*
|
||||
* A special flag to tell the normalisation code not to normalise.
|
||||
*/
|
||||
#define VFP_NAN_FLAG 0x100
|
||||
|
||||
/*
|
||||
* A bit pattern used to indicate the initial (unset) value of the
|
||||
* exception mask, in case nothing handles an instruction. This
|
||||
* doesn't include the NAN flag, which get masked out before
|
||||
* we check for an error.
|
||||
*/
|
||||
#define VFP_EXCEPTION_ERROR ((u32)-1 & ~VFP_NAN_FLAG)
|
||||
|
||||
/*
|
||||
* A flag to tell vfp instruction type.
|
||||
* OP_SCALAR - this operation always operates in scalar mode
|
||||
* OP_SD - the instruction exceptionally writes to a single precision result.
|
||||
* OP_DD - the instruction exceptionally writes to a double precision result.
|
||||
* OP_SM - the instruction exceptionally reads from a single precision operand.
|
||||
*/
|
||||
#define OP_SCALAR (1 << 0)
|
||||
#define OP_SD (1 << 1)
|
||||
#define OP_DD (1 << 1)
|
||||
#define OP_SM (1 << 2)
|
||||
|
||||
struct op {
|
||||
u32 (* const fn)(ARMul_State* state, int dd, int dn, int dm, u32 fpscr);
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
static u32 vfp_fls(int x)
|
||||
{
|
||||
int r = 32;
|
||||
|
||||
if (!x)
|
||||
return 0;
|
||||
if (!(x & 0xffff0000u)) {
|
||||
x <<= 16;
|
||||
r -= 16;
|
||||
}
|
||||
if (!(x & 0xff000000u)) {
|
||||
x <<= 8;
|
||||
r -= 8;
|
||||
}
|
||||
if (!(x & 0xf0000000u)) {
|
||||
x <<= 4;
|
||||
r -= 4;
|
||||
}
|
||||
if (!(x & 0xc0000000u)) {
|
||||
x <<= 2;
|
||||
r -= 2;
|
||||
}
|
||||
if (!(x & 0x80000000u)) {
|
||||
x <<= 1;
|
||||
r -= 1;
|
||||
}
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
1263
src/core/arm/skyeye_common/vfp/vfpdouble.cpp
Normal file
1263
src/core/arm/skyeye_common/vfp/vfpdouble.cpp
Normal file
File diff suppressed because it is too large
Load diff
5123
src/core/arm/skyeye_common/vfp/vfpinstr.cpp
Normal file
5123
src/core/arm/skyeye_common/vfp/vfpinstr.cpp
Normal file
File diff suppressed because it is too large
Load diff
1278
src/core/arm/skyeye_common/vfp/vfpsingle.cpp
Normal file
1278
src/core/arm/skyeye_common/vfp/vfpsingle.cpp
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue