📄 helper.c.svn-base
字号:
*/ if (env->cp15.c13_fcse != val) tlb_flush(env, 1); env->cp15.c13_fcse = val; break; case 1: /* This changes the ASID, so do a TLB flush. */ if (env->cp15.c13_context != val && !arm_feature(env, ARM_FEATURE_MPU)) tlb_flush(env, 0); env->cp15.c13_context = val; break; case 2: env->cp15.c13_tls1 = val; break; case 3: env->cp15.c13_tls2 = val; break; case 4: env->cp15.c13_tls3 = val; break; default: goto bad_reg; } break; case 14: /* Reserved. */ goto bad_reg; case 15: /* Implementation specific. */ if (arm_feature(env, ARM_FEATURE_XSCALE)) { if (op2 == 0 && crm == 1) { if (env->cp15.c15_cpar != (val & 0x3fff)) { /* Changes cp0 to cp13 behavior, so needs a TB flush. */ tb_flush(env); env->cp15.c15_cpar = val & 0x3fff; } break; } goto bad_reg; } if (arm_feature(env, ARM_FEATURE_OMAPCP)) { switch (crm) { case 0: break; case 1: /* Set TI925T configuration. */ env->cp15.c15_ticonfig = val & 0xe7; env->cp15.c0_cpuid = (val & (1 << 5)) ? /* OS_TYPE bit */ ARM_CPUID_TI915T : ARM_CPUID_TI925T; break; case 2: /* Set I_max. */ env->cp15.c15_i_max = val; break; case 3: /* Set I_min. */ env->cp15.c15_i_min = val; break; case 4: /* Set thread-ID. */ env->cp15.c15_threadid = val & 0xffff; break; case 8: /* Wait-for-interrupt (deprecated). */ cpu_interrupt(env, CPU_INTERRUPT_HALT); break; default: goto bad_reg; } } break; } return;bad_reg: /* ??? For debugging only. Should raise illegal instruction exception. */ cpu_abort(env, "Unimplemented cp15 register write (c%d, c%d, {%d, %d})\n", (insn >> 16) & 0xf, crm, op1, op2);}uint32_t helper_get_cp15(CPUState *env, uint32_t insn){ int op1; int op2; int crm; op1 = (insn >> 21) & 7; op2 = (insn >> 5) & 7; crm = insn & 0xf; switch ((insn >> 16) & 0xf) { case 0: /* ID codes. */ switch (op1) { case 0: switch (crm) { case 0: switch (op2) { case 0: /* Device ID. */ return env->cp15.c0_cpuid; case 1: /* Cache Type. */ return env->cp15.c0_cachetype; case 2: /* TCM status. */ return 0; case 3: /* TLB type register. */ return 0; /* No lockable TLB entries. */ case 5: /* CPU ID */ return env->cpu_index; default: goto bad_reg; } case 1: if (!arm_feature(env, ARM_FEATURE_V6)) goto bad_reg; return env->cp15.c0_c1[op2]; case 2: if (!arm_feature(env, ARM_FEATURE_V6)) goto bad_reg; return env->cp15.c0_c2[op2]; case 3: case 4: case 5: case 6: case 7: return 0; default: goto bad_reg; } case 1: /* These registers aren't documented on arm11 cores. However Linux looks at them anyway. */ if (!arm_feature(env, ARM_FEATURE_V6)) goto bad_reg; if (crm != 0) goto bad_reg; if (arm_feature(env, ARM_FEATURE_XSCALE)) goto bad_reg; return 0; default: goto bad_reg; } case 1: /* System configuration. */ if (arm_feature(env, ARM_FEATURE_OMAPCP)) op2 = 0; switch (op2) { case 0: /* Control register. */ return env->cp15.c1_sys; case 1: /* Auxiliary control register. */ if (arm_feature(env, ARM_FEATURE_XSCALE)) return env->cp15.c1_xscaleauxcr; if (!arm_feature(env, ARM_FEATURE_AUXCR)) goto bad_reg; switch (ARM_CPUID(env)) { case ARM_CPUID_ARM1026: return 1; case ARM_CPUID_ARM1136: return 7; case ARM_CPUID_ARM11MPCORE: return 1; case ARM_CPUID_CORTEXA8: return 0; default: goto bad_reg; } case 2: /* Coprocessor access register. */ if (arm_feature(env, ARM_FEATURE_XSCALE)) goto bad_reg; return env->cp15.c1_coproc; default: goto bad_reg; } case 2: /* MMU Page table control / MPU cache control. */ if (arm_feature(env, ARM_FEATURE_MPU)) { switch (op2) { case 0: return env->cp15.c2_data; break; case 1: return env->cp15.c2_insn; break; default: goto bad_reg; } } else { switch (op2) { case 0: return env->cp15.c2_base0; case 1: return env->cp15.c2_base1; case 2: { int n; uint32_t mask; n = 0; mask = env->cp15.c2_mask; while (mask) { n++; mask <<= 1; } return n; } default: goto bad_reg; } } case 3: /* MMU Domain access control / MPU write buffer control. */ return env->cp15.c3; case 4: /* Reserved. */ goto bad_reg; case 5: /* MMU Fault status / MPU access permission. */ if (arm_feature(env, ARM_FEATURE_OMAPCP)) op2 = 0; switch (op2) { case 0: if (arm_feature(env, ARM_FEATURE_MPU)) return simple_mpu_ap_bits(env->cp15.c5_data); return env->cp15.c5_data; case 1: if (arm_feature(env, ARM_FEATURE_MPU)) return simple_mpu_ap_bits(env->cp15.c5_data); return env->cp15.c5_insn; case 2: if (!arm_feature(env, ARM_FEATURE_MPU)) goto bad_reg; return env->cp15.c5_data; case 3: if (!arm_feature(env, ARM_FEATURE_MPU)) goto bad_reg; return env->cp15.c5_insn; default: goto bad_reg; } case 6: /* MMU Fault address. */ if (arm_feature(env, ARM_FEATURE_MPU)) { if (crm >= 8) goto bad_reg; return env->cp15.c6_region[crm]; } else { if (arm_feature(env, ARM_FEATURE_OMAPCP)) op2 = 0; switch (op2) { case 0: return env->cp15.c6_data; case 1: if (arm_feature(env, ARM_FEATURE_V6)) { /* Watchpoint Fault Adrress. */ return 0; /* Not implemented. */ } else { /* Instruction Fault Adrress. */ /* Arm9 doesn't have an IFAR, but implementing it anyway shouldn't do any harm. */ return env->cp15.c6_insn; } case 2: if (arm_feature(env, ARM_FEATURE_V6)) { /* Instruction Fault Adrress. */ return env->cp15.c6_insn; } else { goto bad_reg; } default: goto bad_reg; } } case 7: /* Cache control. */ /* ??? This is for test, clean and invaidate operations that set the Z flag. We can't represent N = Z = 1, so it also clears the N flag. Oh well. */ env->NZF = 0; return 0; case 8: /* MMU TLB control. */ goto bad_reg; case 9: /* Cache lockdown. */ switch (op1) { case 0: /* L1 cache. */ if (arm_feature(env, ARM_FEATURE_OMAPCP)) return 0; switch (op2) { case 0: return env->cp15.c9_data; case 1: return env->cp15.c9_insn; default: goto bad_reg; } case 1: /* L2 cache */ if (crm != 0) goto bad_reg; /* L2 Lockdown and Auxiliary control. */ return 0; default: goto bad_reg; } case 10: /* MMU TLB lockdown. */ /* ??? TLB lockdown not implemented. */ return 0; case 11: /* TCM DMA control. */ case 12: /* Reserved. */ goto bad_reg; case 13: /* Process ID. */ switch (op2) { case 0: return env->cp15.c13_fcse; case 1: return env->cp15.c13_context; case 2: return env->cp15.c13_tls1; case 3: return env->cp15.c13_tls2; case 4: return env->cp15.c13_tls3; default: goto bad_reg; } case 14: /* Reserved. */ goto bad_reg; case 15: /* Implementation specific. */ if (arm_feature(env, ARM_FEATURE_XSCALE)) { if (op2 == 0 && crm == 1) return env->cp15.c15_cpar; goto bad_reg; } if (arm_feature(env, ARM_FEATURE_OMAPCP)) { switch (crm) { case 0: return 0; case 1: /* Read TI925T configuration. */ return env->cp15.c15_ticonfig; case 2: /* Read I_max. */ return env->cp15.c15_i_max; case 3: /* Read I_min. */ return env->cp15.c15_i_min; case 4: /* Read thread-ID. */ return env->cp15.c15_threadid; case 8: /* TI925T_status */ return 0; } goto bad_reg; } return 0; }bad_reg: /* ??? For debugging only. Should raise illegal instruction exception. */ cpu_abort(env, "Unimplemented cp15 register read (c%d, c%d, {%d, %d})\n", (insn >> 16) & 0xf, crm, op1, op2); return 0;}void helper_set_r13_banked(CPUState *env, int mode, uint32_t val){ env->banked_r13[bank_number(mode)] = val;}uint32_t helper_get_r13_banked(CPUState *env, int mode){ return env->banked_r13[bank_number(mode)];}uint32_t helper_v7m_mrs(CPUState *env, int reg){ switch (reg) { case 0: /* APSR */ return xpsr_read(env) & 0xf8000000; case 1: /* IAPSR */ return xpsr_read(env) & 0xf80001ff; case 2: /* EAPSR */ return xpsr_read(env) & 0xff00fc00; case 3: /* xPSR */ return xpsr_read(env) & 0xff00fdff; case 5: /* IPSR */ return xpsr_read(env) & 0x000001ff; case 6: /* EPSR */ return xpsr_read(env) & 0x0700fc00; case 7: /* IEPSR */ return xpsr_read(env) & 0x0700edff; case 8: /* MSP */ return env->v7m.current_sp ? env->v7m.other_sp : env->regs[13]; case 9: /* PSP */ return env->v7m.current_sp ? env->regs[13] : env->v7m.other_sp; case 16: /* PRIMASK */ return (env->uncached_cpsr & CPSR_I) != 0; case 17: /* FAULTMASK */ return (env->uncached_cpsr & CPSR_F) != 0; case 18: /* BASEPRI */ case 19: /* BASEPRI_MAX */ return env->v7m.basepri; case 20: /* CONTROL */ return env->v7m.control; default: /* ??? For debugging only. */ cpu_abort(env, "Unimplemented system register read (%d)\n", reg); return 0; }}void helper_v7m_msr(CPUState *env, int reg, uint32_t val){ switch (reg) { case 0: /* APSR */ xpsr_write(env, val, 0xf8000000); break; case 1: /* IAPSR */ xpsr_write(env, val, 0xf8000000); break; case 2: /* EAPSR */ xpsr_write(env, val, 0xfe00fc00); break; case 3: /* xPSR */ xpsr_write(env, val, 0xfe00fc00); break; case 5: /* IPSR */ /* IPSR bits are readonly. */ break; case 6: /* EPSR */ xpsr_write(env, val, 0x0600fc00); break; case 7: /* IEPSR */ xpsr_write(env, val, 0x0600fc00); break; case 8: /* MSP */ if (env->v7m.current_sp) env->v7m.other_sp = val; else env->regs[13] = val; break; case 9: /* PSP */ if (env->v7m.current_sp) env->regs[13] = val; else env->v7m.other_sp = val; break; case 16: /* PRIMASK */ if (val & 1) env->uncached_cpsr |= CPSR_I; else env->uncached_cpsr &= ~CPSR_I; break; case 17: /* FAULTMASK */ if (val & 1) env->uncached_cpsr |= CPSR_F; else env->uncached_cpsr &= ~CPSR_F; break; case 18: /* BASEPRI */ env->v7m.basepri = val & 0xff; break; case 19: /* BASEPRI_MAX */ val &= 0xff; if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0)) env->v7m.basepri = val; break; case 20: /* CONTROL */ env->v7m.control = val & 3; switch_v7m_sp(env, (val & 2) != 0); break; default: /* ??? For debugging only. */ cpu_abort(env, "Unimplemented system register write (%d)\n", reg); return; }}void cpu_arm_set_cp_io(CPUARMState *env, int cpnum, ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write, void *opaque){ if (cpnum < 0 || cpnum > 14) { cpu_abort(env, "Bad coprocessor number: %i\n", cpnum); return; } env->cp[cpnum].cp_read = cp_read; env->cp[cpnum].cp_write = cp_write; env->cp[cpnum].opaque = opaque;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -