00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef CPU_ARM_H
00021 #define CPU_ARM_H
00022
00023 #define TARGET_LONG_BITS 32
00024
00025 #define ELF_MACHINE EM_ARM
00026
00027 #include "cpu-defs.h"
00028
00029 #include "softfloat.h"
00030
00031 #define TARGET_HAS_ICE 1
00032
00033 #define EXCP_UDEF 1
00034 #define EXCP_SWI 2
00035 #define EXCP_PREFETCH_ABORT 3
00036 #define EXCP_DATA_ABORT 4
00037 #define EXCP_IRQ 5
00038 #define EXCP_FIQ 6
00039 #define EXCP_BKPT 7
00040 #define EXCP_EXCEPTION_EXIT 8
00041 #define EXCP_KERNEL_TRAP 9
00042
00043 #define ARMV7M_EXCP_RESET 1
00044 #define ARMV7M_EXCP_NMI 2
00045 #define ARMV7M_EXCP_HARD 3
00046 #define ARMV7M_EXCP_MEM 4
00047 #define ARMV7M_EXCP_BUS 5
00048 #define ARMV7M_EXCP_USAGE 6
00049 #define ARMV7M_EXCP_SVC 11
00050 #define ARMV7M_EXCP_DEBUG 12
00051 #define ARMV7M_EXCP_PENDSV 14
00052 #define ARMV7M_EXCP_SYSTICK 15
00053
00054 typedef void ARMWriteCPFunc(void *opaque, int cp_info,
00055 int srcreg, int operand, uint32_t value);
00056 typedef uint32_t ARMReadCPFunc(void *opaque, int cp_info,
00057 int dstreg, int operand);
00058
00059 struct arm_boot_info;
00060
00061 #define NB_MMU_MODES 2
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 typedef struct CPUARMState {
00072
00073 uint32_t regs[16];
00074
00075
00076
00077 uint32_t uncached_cpsr;
00078 uint32_t spsr;
00079
00080
00081 uint32_t banked_spsr[6];
00082 uint32_t banked_r13[6];
00083 uint32_t banked_r14[6];
00084
00085
00086 uint32_t usr_regs[5];
00087 uint32_t fiq_regs[5];
00088
00089
00090 uint32_t CF;
00091 uint32_t VF;
00092 uint32_t NF;
00093 uint32_t ZF;
00094 uint32_t QF;
00095 uint32_t GE;
00096 uint32_t thumb;
00097 uint32_t condexec_bits;
00098
00099
00100 struct {
00101 uint32_t c0_cpuid;
00102 uint32_t c0_cachetype;
00103 uint32_t c0_ccsid[16];
00104 uint32_t c0_clid;
00105 uint32_t c0_cssel;
00106 uint32_t c0_c1[8];
00107 uint32_t c0_c2[8];
00108 uint32_t c1_sys;
00109 uint32_t c1_coproc;
00110 uint32_t c1_xscaleauxcr;
00111 uint32_t c2_base0;
00112 uint32_t c2_base1;
00113 uint32_t c2_control;
00114 uint32_t c2_mask;
00115 uint32_t c2_base_mask;
00116 uint32_t c2_data;
00117 uint32_t c2_insn;
00118 uint32_t c3;
00119
00120 uint32_t c5_insn;
00121 uint32_t c5_data;
00122 uint32_t c6_region[8];
00123 uint32_t c6_insn;
00124 uint32_t c6_data;
00125 uint32_t c9_insn;
00126 uint32_t c9_data;
00127 uint32_t c13_fcse;
00128 uint32_t c13_context;
00129 uint32_t c13_tls1;
00130 uint32_t c13_tls2;
00131 uint32_t c13_tls3;
00132 uint32_t c15_cpar;
00133 uint32_t c15_ticonfig;
00134 uint32_t c15_i_max;
00135 uint32_t c15_i_min;
00136 uint32_t c15_threadid;
00137 } cp15;
00138
00139 struct {
00140 uint32_t other_sp;
00141 uint32_t vecbase;
00142 uint32_t basepri;
00143 uint32_t control;
00144 int current_sp;
00145 int exception;
00146 int pending_exception;
00147 void *nvic;
00148 } v7m;
00149
00150
00151 struct {
00152 ARMReadCPFunc *cp_read;
00153 ARMWriteCPFunc *cp_write;
00154 void *opaque;
00155 } cp[15];
00156
00157
00158 uint32_t teecr;
00159 uint32_t teehbr;
00160
00161
00162 uint32_t features;
00163
00164
00165 int (*get_irq_vector)(struct CPUARMState *);
00166 void *irq_opaque;
00167
00168
00169 struct {
00170 float64 regs[32];
00171
00172 uint32_t xregs[16];
00173
00174 int vec_len;
00175 int vec_stride;
00176
00177
00178 uint32_t scratch[8];
00179
00180 float_status fp_status;
00181 } vfp;
00182 #if defined(CONFIG_USER_ONLY)
00183 struct mmon_state *mmon_entry;
00184 #else
00185 uint32_t mmon_addr;
00186 #endif
00187
00188
00189 struct {
00190 uint64_t regs[16];
00191 uint64_t val;
00192
00193 uint32_t cregs[16];
00194 } iwmmxt;
00195
00196 #if defined(CONFIG_USER_ONLY)
00197
00198 int eabi;
00199 #endif
00200
00201 CPU_COMMON
00202
00203
00204 struct arm_boot_info *boot_info;
00205 } CPUARMState;
00206
00207 CPUARMState *cpu_arm_init(const char *cpu_model);
00208 void arm_translate_init(void);
00209 int cpu_arm_exec(CPUARMState *s);
00210 void cpu_arm_close(CPUARMState *s);
00211 void do_interrupt(CPUARMState *);
00212 void switch_mode(CPUARMState *, int);
00213 uint32_t do_arm_semihosting(CPUARMState *env);
00214
00215
00216
00217
00218 int cpu_arm_signal_handler(int host_signum, void *pinfo,
00219 void *puc);
00220 int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
00221 int mmu_idx, int is_softmuu);
00222
00223 void cpu_lock(void);
00224 void cpu_unlock(void);
00225 static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
00226 {
00227 env->cp15.c13_tls2 = newtls;
00228 }
00229
00230 #define CPSR_M (0x1f)
00231 #define CPSR_T (1 << 5)
00232 #define CPSR_F (1 << 6)
00233 #define CPSR_I (1 << 7)
00234 #define CPSR_A (1 << 8)
00235 #define CPSR_E (1 << 9)
00236 #define CPSR_IT_2_7 (0xfc00)
00237 #define CPSR_GE (0xf << 16)
00238 #define CPSR_RESERVED (0xf << 20)
00239 #define CPSR_J (1 << 24)
00240 #define CPSR_IT_0_1 (3 << 25)
00241 #define CPSR_Q (1 << 27)
00242 #define CPSR_V (1 << 28)
00243 #define CPSR_C (1 << 29)
00244 #define CPSR_Z (1 << 30)
00245 #define CPSR_N (1 << 31)
00246 #define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V)
00247
00248 #define CPSR_IT (CPSR_IT_0_1 | CPSR_IT_2_7)
00249 #define CACHED_CPSR_BITS (CPSR_T | CPSR_GE | CPSR_IT | CPSR_Q | CPSR_NZCV)
00250
00251 #define CPSR_USER (CPSR_NZCV | CPSR_Q | CPSR_GE)
00252
00253 #define CPSR_EXEC (CPSR_T | CPSR_IT | CPSR_J)
00254
00255
00256 uint32_t cpsr_read(CPUARMState *env);
00257
00258 void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask);
00259
00260
00261 static inline uint32_t xpsr_read(CPUARMState *env)
00262 {
00263 int ZF;
00264 ZF = (env->ZF == 0);
00265 return (env->NF & 0x80000000) | (ZF << 30)
00266 | (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
00267 | (env->thumb << 24) | ((env->condexec_bits & 3) << 25)
00268 | ((env->condexec_bits & 0xfc) << 8)
00269 | env->v7m.exception;
00270 }
00271
00272
00273 static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
00274 {
00275 if (mask & CPSR_NZCV) {
00276 env->ZF = (~val) & CPSR_Z;
00277 env->NF = val;
00278 env->CF = (val >> 29) & 1;
00279 env->VF = (val << 3) & 0x80000000;
00280 }
00281 if (mask & CPSR_Q)
00282 env->QF = ((val & CPSR_Q) != 0);
00283 if (mask & (1 << 24))
00284 env->thumb = ((val & (1 << 24)) != 0);
00285 if (mask & CPSR_IT_0_1) {
00286 env->condexec_bits &= ~3;
00287 env->condexec_bits |= (val >> 25) & 3;
00288 }
00289 if (mask & CPSR_IT_2_7) {
00290 env->condexec_bits &= 3;
00291 env->condexec_bits |= (val >> 8) & 0xfc;
00292 }
00293 if (mask & 0x1ff) {
00294 env->v7m.exception = val & 0x1ff;
00295 }
00296 }
00297
00298 enum arm_cpu_mode {
00299 ARM_CPU_MODE_USR = 0x10,
00300 ARM_CPU_MODE_FIQ = 0x11,
00301 ARM_CPU_MODE_IRQ = 0x12,
00302 ARM_CPU_MODE_SVC = 0x13,
00303 ARM_CPU_MODE_ABT = 0x17,
00304 ARM_CPU_MODE_UND = 0x1b,
00305 ARM_CPU_MODE_SYS = 0x1f
00306 };
00307
00308
00309 #define ARM_VFP_FPSID 0
00310 #define ARM_VFP_FPSCR 1
00311 #define ARM_VFP_MVFR1 6
00312 #define ARM_VFP_MVFR0 7
00313 #define ARM_VFP_FPEXC 8
00314 #define ARM_VFP_FPINST 9
00315 #define ARM_VFP_FPINST2 10
00316
00317
00318 #define ARM_IWMMXT_wCID 0
00319 #define ARM_IWMMXT_wCon 1
00320 #define ARM_IWMMXT_wCSSF 2
00321 #define ARM_IWMMXT_wCASF 3
00322 #define ARM_IWMMXT_wCGR0 8
00323 #define ARM_IWMMXT_wCGR1 9
00324 #define ARM_IWMMXT_wCGR2 10
00325 #define ARM_IWMMXT_wCGR3 11
00326
00327 enum arm_features {
00328 ARM_FEATURE_VFP,
00329 ARM_FEATURE_AUXCR,
00330 ARM_FEATURE_XSCALE,
00331 ARM_FEATURE_IWMMXT,
00332 ARM_FEATURE_V6,
00333 ARM_FEATURE_V6K,
00334 ARM_FEATURE_V7,
00335 ARM_FEATURE_THUMB2,
00336 ARM_FEATURE_MPU,
00337 ARM_FEATURE_VFP3,
00338 ARM_FEATURE_NEON,
00339 ARM_FEATURE_DIV,
00340 ARM_FEATURE_M,
00341 ARM_FEATURE_OMAPCP,
00342 ARM_FEATURE_THUMB2EE
00343 };
00344
00345 static inline int arm_feature(CPUARMState *env, int feature)
00346 {
00347 return (env->features & (1u << feature)) != 0;
00348 }
00349
00350 void arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
00351
00352
00353 void armv7m_nvic_set_pending(void *opaque, int irq);
00354 int armv7m_nvic_acknowledge_irq(void *opaque);
00355 void armv7m_nvic_complete_irq(void *opaque, int irq);
00356
00357 void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
00358 ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write,
00359 void *opaque);
00360
00361
00362
00363
00364
00365 #define IS_M(env) arm_feature(env, ARM_FEATURE_M)
00366 #define ARM_CPUID(env) (env->cp15.c0_cpuid)
00367
00368 #define ARM_CPUID_ARM1026 0x4106a262
00369 #define ARM_CPUID_ARM926 0x41069265
00370 #define ARM_CPUID_ARM946 0x41059461
00371 #define ARM_CPUID_TI915T 0x54029152
00372 #define ARM_CPUID_TI925T 0x54029252
00373 #define ARM_CPUID_PXA250 0x69052100
00374 #define ARM_CPUID_PXA255 0x69052d00
00375 #define ARM_CPUID_PXA260 0x69052903
00376 #define ARM_CPUID_PXA261 0x69052d05
00377 #define ARM_CPUID_PXA262 0x69052d06
00378 #define ARM_CPUID_PXA270 0x69054110
00379 #define ARM_CPUID_PXA270_A0 0x69054110
00380 #define ARM_CPUID_PXA270_A1 0x69054111
00381 #define ARM_CPUID_PXA270_B0 0x69054112
00382 #define ARM_CPUID_PXA270_B1 0x69054113
00383 #define ARM_CPUID_PXA270_C0 0x69054114
00384 #define ARM_CPUID_PXA270_C5 0x69054117
00385 #define ARM_CPUID_ARM1136 0x4117b363
00386 #define ARM_CPUID_ARM1136_R2 0x4107b362
00387 #define ARM_CPUID_ARM11MPCORE 0x410fb022
00388 #define ARM_CPUID_CORTEXA8 0x410fc080
00389 #define ARM_CPUID_CORTEXM3 0x410fc231
00390 #define ARM_CPUID_ANY 0xffffffff
00391
00392 #if defined(CONFIG_USER_ONLY)
00393 #define TARGET_PAGE_BITS 12
00394 #else
00395
00396
00397
00398 #define TARGET_PAGE_BITS 10
00399 #endif
00400
00401 #define CPUState CPUARMState
00402 #define cpu_init cpu_arm_init
00403 #define cpu_exec cpu_arm_exec
00404 #define cpu_gen_code cpu_arm_gen_code
00405 #define cpu_signal_handler cpu_arm_signal_handler
00406 #define cpu_list arm_cpu_list
00407
00408 #define CPU_SAVE_VERSION 1
00409
00410
00411 #define MMU_MODE0_SUFFIX _kernel
00412 #define MMU_MODE1_SUFFIX _user
00413 #define MMU_USER_IDX 1
00414 static inline int cpu_mmu_index (CPUState *env)
00415 {
00416 return (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR ? 1 : 0;
00417 }
00418
00419 #if defined(CONFIG_USER_ONLY)
00420 static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
00421 {
00422 if (newsp)
00423 env->regs[13] = newsp;
00424 env->regs[0] = 0;
00425 }
00426 #endif
00427
00428 #include "cpu-all.h"
00429 #include "exec-all.h"
00430
00431 static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
00432 {
00433 env->regs[15] = tb->pc;
00434 }
00435
00436 static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
00437 target_ulong *cs_base, int *flags)
00438 {
00439 *pc = env->regs[15];
00440 *cs_base = 0;
00441 *flags = env->thumb | (env->vfp.vec_len << 1)
00442 | (env->vfp.vec_stride << 4) | (env->condexec_bits << 8);
00443 if ((env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR)
00444 *flags |= (1 << 6);
00445 if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30))
00446 *flags |= (1 << 7);
00447 }
00448
00449 #endif