?? helper.c
字號:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include "cpu.h"#include "exec-all.h"#include "gdbstub.h"static uint32_t cortexa8_cp15_c0_c1[8] ={ 0x1031, 0x11, 0x400, 0, 0x31100003, 0x20000000, 0x01202000, 0x11 };static uint32_t cortexa8_cp15_c0_c2[8] ={ 0x00101111, 0x12112111, 0x21232031, 0x11112131, 0x00111142, 0, 0, 0 };static uint32_t mpcore_cp15_c0_c1[8] ={ 0x111, 0x1, 0, 0x2, 0x01100103, 0x10020302, 0x01222000, 0 };static uint32_t mpcore_cp15_c0_c2[8] ={ 0x00100011, 0x12002111, 0x11221011, 0x01102131, 0x141, 0, 0, 0 };static uint32_t arm1136_cp15_c0_c1[8] ={ 0x111, 0x1, 0x2, 0x3, 0x01130003, 0x10030302, 0x01222110, 0 };static uint32_t arm1136_cp15_c0_c2[8] ={ 0x00140011, 0x12002111, 0x11231111, 0x01102131, 0x141, 0, 0, 0 };static uint32_t cpu_arm_find_by_name(const char *name);static inline void set_feature(CPUARMState *env, int feature){ env->features |= 1u << feature;}static void cpu_reset_model_id(CPUARMState *env, uint32_t id){ env->cp15.c0_cpuid = id; switch (id) { case ARM_CPUID_ARM926: set_feature(env, ARM_FEATURE_VFP); env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090; env->cp15.c0_cachetype = 0x1dd20d2; env->cp15.c1_sys = 0x00090078; break; case ARM_CPUID_ARM946: set_feature(env, ARM_FEATURE_MPU); env->cp15.c0_cachetype = 0x0f004006; env->cp15.c1_sys = 0x00000078; break; case ARM_CPUID_ARM1026: set_feature(env, ARM_FEATURE_VFP); set_feature(env, ARM_FEATURE_AUXCR); env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0; env->cp15.c0_cachetype = 0x1dd20d2; env->cp15.c1_sys = 0x00090078; break; case ARM_CPUID_ARM1136: set_feature(env, ARM_FEATURE_V6); set_feature(env, ARM_FEATURE_VFP); set_feature(env, ARM_FEATURE_AUXCR); env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4; env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111; env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000; memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c2, 8 * sizeof(uint32_t)); env->cp15.c0_cachetype = 0x1dd20d2; break; case ARM_CPUID_ARM11MPCORE: set_feature(env, ARM_FEATURE_V6); set_feature(env, ARM_FEATURE_V6K); set_feature(env, ARM_FEATURE_VFP); set_feature(env, ARM_FEATURE_AUXCR); env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4; env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111; env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000; memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c2, 8 * sizeof(uint32_t)); env->cp15.c0_cachetype = 0x1dd20d2; break; case ARM_CPUID_CORTEXA8: set_feature(env, ARM_FEATURE_V6); set_feature(env, ARM_FEATURE_V6K); set_feature(env, ARM_FEATURE_V7); set_feature(env, ARM_FEATURE_AUXCR); set_feature(env, ARM_FEATURE_THUMB2); set_feature(env, ARM_FEATURE_VFP); set_feature(env, ARM_FEATURE_VFP3); set_feature(env, ARM_FEATURE_NEON); env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0; env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222; env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100; memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c1, 8 * sizeof(uint32_t)); memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c2, 8 * sizeof(uint32_t)); env->cp15.c0_cachetype = 0x1dd20d2; break; case ARM_CPUID_CORTEXM3: set_feature(env, ARM_FEATURE_V6); set_feature(env, ARM_FEATURE_THUMB2); set_feature(env, ARM_FEATURE_V7); set_feature(env, ARM_FEATURE_M); set_feature(env, ARM_FEATURE_DIV); break; case ARM_CPUID_ANY: /* For userspace emulation. */ set_feature(env, ARM_FEATURE_V6); set_feature(env, ARM_FEATURE_V6K); set_feature(env, ARM_FEATURE_V7); set_feature(env, ARM_FEATURE_THUMB2); set_feature(env, ARM_FEATURE_VFP); set_feature(env, ARM_FEATURE_VFP3); set_feature(env, ARM_FEATURE_NEON); set_feature(env, ARM_FEATURE_DIV); break; case ARM_CPUID_TI915T: case ARM_CPUID_TI925T: set_feature(env, ARM_FEATURE_OMAPCP); env->cp15.c0_cpuid = ARM_CPUID_TI925T; /* Depends on wiring. */ env->cp15.c0_cachetype = 0x5109149; env->cp15.c1_sys = 0x00000070; env->cp15.c15_i_max = 0x000; env->cp15.c15_i_min = 0xff0; break; case ARM_CPUID_PXA250: case ARM_CPUID_PXA255: case ARM_CPUID_PXA260: case ARM_CPUID_PXA261: case ARM_CPUID_PXA262: set_feature(env, ARM_FEATURE_XSCALE); /* JTAG_ID is ((id << 28) | 0x09265013) */ env->cp15.c0_cachetype = 0xd172172; env->cp15.c1_sys = 0x00000078; break; case ARM_CPUID_PXA270_A0: case ARM_CPUID_PXA270_A1: case ARM_CPUID_PXA270_B0: case ARM_CPUID_PXA270_B1: case ARM_CPUID_PXA270_C0: case ARM_CPUID_PXA270_C5: set_feature(env, ARM_FEATURE_XSCALE); /* JTAG_ID is ((id << 28) | 0x09265013) */ set_feature(env, ARM_FEATURE_IWMMXT); env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; env->cp15.c0_cachetype = 0xd172172; env->cp15.c1_sys = 0x00000078; break; default: cpu_abort(env, "Bad CPU ID: %x\n", id); break; }}void cpu_reset(CPUARMState *env){ uint32_t id; id = env->cp15.c0_cpuid; memset(env, 0, offsetof(CPUARMState, breakpoints)); if (id) cpu_reset_model_id(env, id);#if defined (CONFIG_USER_ONLY) env->uncached_cpsr = ARM_CPU_MODE_USR; env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30;#else /* SVC mode with interrupts disabled. */ env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I; /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is clear at reset. */ if (IS_M(env)) env->uncached_cpsr &= ~CPSR_I; env->vfp.xregs[ARM_VFP_FPEXC] = 0;#endif env->regs[15] = 0; tlb_flush(env, 1);}CPUARMState *cpu_arm_init(const char *cpu_model){ CPUARMState *env; uint32_t id; id = cpu_arm_find_by_name(cpu_model); if (id == 0) return NULL; env = qemu_mallocz(sizeof(CPUARMState)); if (!env) return NULL; cpu_exec_init(env); env->cpu_model_str = cpu_model; env->cp15.c0_cpuid = id; cpu_reset(env); return env;}struct arm_cpu_t { uint32_t id; const char *name;};static const struct arm_cpu_t arm_cpu_names[] = { { ARM_CPUID_ARM926, "arm926"}, { ARM_CPUID_ARM946, "arm946"}, { ARM_CPUID_ARM1026, "arm1026"}, { ARM_CPUID_ARM1136, "arm1136"}, { ARM_CPUID_ARM11MPCORE, "arm11mpcore"}, { ARM_CPUID_CORTEXM3, "cortex-m3"}, { ARM_CPUID_CORTEXA8, "cortex-a8"}, { ARM_CPUID_TI925T, "ti925t" }, { ARM_CPUID_PXA250, "pxa250" }, { ARM_CPUID_PXA255, "pxa255" }, { ARM_CPUID_PXA260, "pxa260" }, { ARM_CPUID_PXA261, "pxa261" }, { ARM_CPUID_PXA262, "pxa262" }, { ARM_CPUID_PXA270, "pxa270" }, { ARM_CPUID_PXA270_A0, "pxa270-a0" }, { ARM_CPUID_PXA270_A1, "pxa270-a1" }, { ARM_CPUID_PXA270_B0, "pxa270-b0" }, { ARM_CPUID_PXA270_B1, "pxa270-b1" }, { ARM_CPUID_PXA270_C0, "pxa270-c0" }, { ARM_CPUID_PXA270_C5, "pxa270-c5" }, { ARM_CPUID_ANY, "any"}, { 0, NULL}};void arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)){ int i; (*cpu_fprintf)(f, "Available CPUs:\n"); for (i = 0; arm_cpu_names[i].name; i++) { (*cpu_fprintf)(f, " %s\n", arm_cpu_names[i].name); }}/* return 0 if not found */static uint32_t cpu_arm_find_by_name(const char *name){ int i; uint32_t id; id = 0; for (i = 0; arm_cpu_names[i].name; i++) { if (strcmp(name, arm_cpu_names[i].name) == 0) { id = arm_cpu_names[i].id; break; } } return id;}void cpu_arm_close(CPUARMState *env){ free(env);}/* Polynomial multiplication is like integer multiplcation except the partial products are XORed, not added. */uint32_t helper_neon_mul_p8(uint32_t op1, uint32_t op2){ uint32_t mask; uint32_t result; result = 0; while (op1) { mask = 0; if (op1 & 1) mask |= 0xff; if (op1 & (1 << 8)) mask |= (0xff << 8); if (op1 & (1 << 16)) mask |= (0xff << 16); if (op1 & (1 << 24)) mask |= (0xff << 24); result ^= op2 & mask; op1 = (op1 >> 1) & 0x7f7f7f7f; op2 = (op2 << 1) & 0xfefefefe; } return result;}uint32_t cpsr_read(CPUARMState *env){ int ZF; ZF = (env->NZF == 0); return env->uncached_cpsr | (env->NZF & 0x80000000) | (ZF << 30) | (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27) | (env->thumb << 5) | ((env->condexec_bits & 3) << 25) | ((env->condexec_bits & 0xfc) << 8) | (env->GE << 16);}void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask){ /* NOTE: N = 1 and Z = 1 cannot be stored currently */ if (mask & CPSR_NZCV) { env->NZF = (val & 0xc0000000) ^ 0x40000000; env->CF = (val >> 29) & 1; env->VF = (val << 3) & 0x80000000; } if (mask & CPSR_Q) env->QF = ((val & CPSR_Q) != 0); if (mask & CPSR_T) env->thumb = ((val & CPSR_T) != 0); if (mask & CPSR_IT_0_1) { env->condexec_bits &= ~3; env->condexec_bits |= (val >> 25) & 3; } if (mask & CPSR_IT_2_7) { env->condexec_bits &= 3; env->condexec_bits |= (val >> 8) & 0xfc; } if (mask & CPSR_GE) { env->GE = (val >> 16) & 0xf; } if ((env->uncached_cpsr ^ val) & mask & CPSR_M) { switch_mode(env, val & CPSR_M); } mask &= ~CACHED_CPSR_BITS; env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);}#if defined(CONFIG_USER_ONLY)void do_interrupt (CPUState *env){ env->exception_index = -1;}/* Structure used to record exclusive memory locations. */typedef struct mmon_state { struct mmon_state *next; CPUARMState *cpu_env; uint32_t addr;} mmon_state;/* Chain of current locks. */static mmon_state* mmon_head = NULL;int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw, int mmu_idx, int is_softmmu){ if (rw == 2) { env->exception_index = EXCP_PREFETCH_ABORT; env->cp15.c6_insn = address; } else { env->exception_index = EXCP_DATA_ABORT; env->cp15.c6_data = address; } return 1;}static void allocate_mmon_state(CPUState *env){ env->mmon_entry = malloc(sizeof (mmon_state)); if (!env->mmon_entry) abort(); memset (env->mmon_entry, 0, sizeof (mmon_state)); env->mmon_entry->cpu_env = env; mmon_head = env->mmon_entry;}/* Flush any monitor locks for the specified address. */static void flush_mmon(uint32_t addr){ mmon_state *mon; for (mon = mmon_head; mon; mon = mon->next) { if (mon->addr != addr) continue; mon->addr = 0; break; }}/* Mark an address for exclusive access. */void helper_mark_exclusive(CPUState *env, uint32_t addr){ if (!env->mmon_entry) allocate_mmon_state(env); /* Clear any previous locks. */ flush_mmon(addr); env->mmon_entry->addr = addr;}/* Test if an exclusive address is still exclusive. Returns zero if the address is still exclusive. */int helper_test_exclusive(CPUState *env, uint32_t addr){ int res; if (!env->mmon_entry) return 1; if (env->mmon_entry->addr == addr) res = 0; else res = 1; flush_mmon(addr); return res;}void helper_clrex(CPUState *env){ if (!(env->mmon_entry && env->mmon_entry->addr)) return; flush_mmon(env->mmon_entry->addr);}target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr){ return addr;}/* These should probably raise undefined insn exceptions. */void helper_set_cp(CPUState *env, uint32_t insn, uint32_t val){ int op1 = (insn >> 8) & 0xf; cpu_abort(env, "cp%i insn %08x\n", op1, insn); return;}uint32_t helper_get_cp(CPUState *env, uint32_t insn){ int op1 = (insn >> 8) & 0xf; cpu_abort(env, "cp%i insn %08x\n", op1, insn); return 0;}void helper_set_cp15(CPUState *env, uint32_t insn, uint32_t val){ cpu_abort(env, "cp15 insn %08x\n", insn);}uint32_t helper_get_cp15(CPUState *env, uint32_t insn){ cpu_abort(env, "cp15 insn %08x\n", insn); return 0;}/* These should probably raise undefined insn exceptions. */void helper_v7m_msr(CPUState *env, int reg, uint32_t val){ cpu_abort(env, "v7m_mrs %d\n", reg);}uint32_t helper_v7m_mrs(CPUState *env, int reg){ cpu_abort(env, "v7m_mrs %d\n", reg); return 0;}void switch_mode(CPUState *env, int mode){ if (mode != ARM_CPU_MODE_USR) cpu_abort(env, "Tried to switch out of user mode\n");}void helper_set_r13_banked(CPUState *env, int mode, uint32_t val){ cpu_abort(env, "banked r13 write\n");}uint32_t helper_get_r13_banked(CPUState *env, int mode){ cpu_abort(env, "banked r13 read\n"); return 0;}#else
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -