mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-11 21:25:38 +00:00
target/arm/helper: Correct bad merge
This commit is contained in:
parent
14c1fcd5bf
commit
c93c3bd4b3
|
@ -1989,7 +1989,7 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
|
||||||
/* We do not set any attribute bits in the PAR */
|
/* We do not set any attribute bits in the PAR */
|
||||||
if (page_size == (1 << 24)
|
if (page_size == (1 << 24)
|
||||||
&& arm_feature(env, ARM_FEATURE_V7)) {
|
&& arm_feature(env, ARM_FEATURE_V7)) {
|
||||||
par64 = (phys_addr & 0xff000000) | 1 << 1;
|
par64 = (phys_addr & 0xff000000) | (1 << 1);
|
||||||
} else {
|
} else {
|
||||||
par64 = phys_addr & 0xfffff000;
|
par64 = phys_addr & 0xfffff000;
|
||||||
}
|
}
|
||||||
|
@ -2310,7 +2310,7 @@ static void vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the masks corresponding to the the TCR bank being written
|
/* Update the masks corresponding to the TCR bank being written
|
||||||
* Note that we always calculate mask and base_mask, but
|
* Note that we always calculate mask and base_mask, but
|
||||||
* they are only used for short-descriptor tables (ie if EAE is 0);
|
* they are only used for short-descriptor tables (ie if EAE is 0);
|
||||||
* for long-descriptor tables the TCR fields are used differently
|
* for long-descriptor tables the TCR fields are used differently
|
||||||
|
@ -2608,7 +2608,6 @@ static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||||
if (arm_feature(env, ARM_FEATURE_EL2) && !secure && cur_el == 1) {
|
if (arm_feature(env, ARM_FEATURE_EL2) && !secure && cur_el == 1) {
|
||||||
return env->cp15.vmpidr_el2;
|
return env->cp15.vmpidr_el2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mpidr_read_val(env);
|
return mpidr_read_val(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2738,7 +2737,6 @@ static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
* stage 2 translations, whereas most other scopes only invalidate
|
* stage 2 translations, whereas most other scopes only invalidate
|
||||||
* stage 1 translations.
|
* stage 1 translations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ARMCPU *cpu = arm_env_get_cpu(env);
|
ARMCPU *cpu = arm_env_get_cpu(env);
|
||||||
CPUState *cs = CPU(cpu);
|
CPUState *cs = CPU(cpu);
|
||||||
|
|
||||||
|
@ -4256,10 +4254,6 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
||||||
define_arm_cp_regs(cpu, v7mp_cp_reginfo);
|
define_arm_cp_regs(cpu, v7mp_cp_reginfo);
|
||||||
}
|
}
|
||||||
if (arm_feature(env, ARM_FEATURE_V7)) {
|
if (arm_feature(env, ARM_FEATURE_V7)) {
|
||||||
ARMCPRegInfo clidr = {
|
|
||||||
"CLIDR", 0,0,0, 3,1,1, ARM_CP_STATE_BOTH,
|
|
||||||
ARM_CP_CONST, PL1_R, 0, NULL, cpu->clidr
|
|
||||||
};
|
|
||||||
/* v7 performance monitor control register: same implementor
|
/* v7 performance monitor control register: same implementor
|
||||||
* field as main ID register, and we implement only the cycle
|
* field as main ID register, and we implement only the cycle
|
||||||
* count register.
|
* count register.
|
||||||
|
@ -4278,6 +4272,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
||||||
define_one_arm_cp_reg(cpu, &pmcr);
|
define_one_arm_cp_reg(cpu, &pmcr);
|
||||||
define_one_arm_cp_reg(cpu, &pmcr64);
|
define_one_arm_cp_reg(cpu, &pmcr64);
|
||||||
#endif
|
#endif
|
||||||
|
ARMCPRegInfo clidr = {
|
||||||
|
"CLIDR", 0,0,0, 3,1,1, ARM_CP_STATE_BOTH,
|
||||||
|
ARM_CP_CONST, PL1_R, 0, NULL, cpu->clidr
|
||||||
|
};
|
||||||
define_one_arm_cp_reg(cpu, &clidr);
|
define_one_arm_cp_reg(cpu, &clidr);
|
||||||
define_arm_cp_regs(cpu, v7_cp_reginfo);
|
define_arm_cp_regs(cpu, v7_cp_reginfo);
|
||||||
define_debug_regs(cpu);
|
define_debug_regs(cpu);
|
||||||
|
@ -4600,6 +4598,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
||||||
ARM_CP_CONST, PL1_R, 0, NULL, 0 },
|
ARM_CP_CONST, PL1_R, 0, NULL, 0 },
|
||||||
REGINFO_SENTINEL
|
REGINFO_SENTINEL
|
||||||
};
|
};
|
||||||
|
/* TLBTR is specific to VMSA */
|
||||||
ARMCPRegInfo id_tlbtr_reginfo = {
|
ARMCPRegInfo id_tlbtr_reginfo = {
|
||||||
"TLBTR", 15,0,0, 0,0,3, 0,
|
"TLBTR", 15,0,0, 0,0,3, 0,
|
||||||
ARM_CP_CONST, PL1_R, 0, NULL, 0,
|
ARM_CP_CONST, PL1_R, 0, NULL, 0,
|
||||||
|
@ -4818,6 +4817,7 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
|
||||||
* necessary as the register may have been defined with both states.
|
* necessary as the register may have been defined with both states.
|
||||||
*/
|
*/
|
||||||
r2->secure = secstate;
|
r2->secure = secstate;
|
||||||
|
|
||||||
if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
|
if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
|
||||||
/* Register is banked (using both entries in array).
|
/* Register is banked (using both entries in array).
|
||||||
* Overwriting fieldoffset as the array is only used to define
|
* Overwriting fieldoffset as the array is only used to define
|
||||||
|
@ -4863,7 +4863,6 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == ARM_CP_STATE_AA64) {
|
if (state == ARM_CP_STATE_AA64) {
|
||||||
/* To allow abbreviation of ARMCPRegInfo
|
/* To allow abbreviation of ARMCPRegInfo
|
||||||
* definitions, we treat cp == 0 as equivalent to
|
* definitions, we treat cp == 0 as equivalent to
|
||||||
|
@ -5679,6 +5678,7 @@ static void write_v7m_control_spsel_for_secstate(CPUARMState *env,
|
||||||
if (secstate == env->v7m.secure) {
|
if (secstate == env->v7m.secure) {
|
||||||
bool new_is_psp = v7m_using_psp(env);
|
bool new_is_psp = v7m_using_psp(env);
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
|
|
||||||
if (old_is_psp != new_is_psp) {
|
if (old_is_psp != new_is_psp) {
|
||||||
tmp = env->v7m.other_sp;
|
tmp = env->v7m.other_sp;
|
||||||
env->v7m.other_sp = env->regs[13];
|
env->v7m.other_sp = env->regs[13];
|
||||||
|
@ -6128,6 +6128,7 @@ static bool v7m_push_stack(ARMCPU *cpu)
|
||||||
frameptr -= 4;
|
frameptr -= 4;
|
||||||
xpsr |= XPSR_SPREALIGN;
|
xpsr |= XPSR_SPREALIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
frameptr -= 0x20;
|
frameptr -= 0x20;
|
||||||
|
|
||||||
/* Write as much of the stack frame as we can. If we fail a stack
|
/* Write as much of the stack frame as we can. If we fail a stack
|
||||||
|
@ -6160,7 +6161,6 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
|
||||||
CPUState *cs = CPU(cpu);
|
CPUState *cs = CPU(cpu);
|
||||||
uint32_t excret;
|
uint32_t excret;
|
||||||
uint32_t xpsr;
|
uint32_t xpsr;
|
||||||
|
|
||||||
bool ufault = false;
|
bool ufault = false;
|
||||||
bool sfault = false;
|
bool sfault = false;
|
||||||
bool return_to_sp_process;
|
bool return_to_sp_process;
|
||||||
|
@ -6486,6 +6486,79 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
|
||||||
qemu_log_mask(CPU_LOG_INT, "...successful exception return\n");
|
qemu_log_mask(CPU_LOG_INT, "...successful exception return\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool do_v7m_function_return(ARMCPU *cpu)
|
||||||
|
{
|
||||||
|
/* v8M security extensions magic function return.
|
||||||
|
* We may either:
|
||||||
|
* (1) throw an exception (longjump)
|
||||||
|
* (2) return true if we successfully handled the function return
|
||||||
|
* (3) return false if we failed a consistency check and have
|
||||||
|
* pended a UsageFault that needs to be taken now
|
||||||
|
*
|
||||||
|
* At this point the magic return value is split between env->regs[15]
|
||||||
|
* and env->thumb. We don't bother to reconstitute it because we don't
|
||||||
|
* need it (all values are handled the same way).
|
||||||
|
*/
|
||||||
|
CPUARMState *env = &cpu->env;
|
||||||
|
uint32_t newpc, newpsr, newpsr_exc;
|
||||||
|
|
||||||
|
qemu_log_mask(CPU_LOG_INT, "...really v7M secure function return\n");
|
||||||
|
|
||||||
|
{
|
||||||
|
bool threadmode, spsel;
|
||||||
|
TCGMemOpIdx oi;
|
||||||
|
ARMMMUIdx mmu_idx;
|
||||||
|
uint32_t *frame_sp_p;
|
||||||
|
uint32_t frameptr;
|
||||||
|
|
||||||
|
/* Pull the return address and IPSR from the Secure stack */
|
||||||
|
threadmode = !arm_v7m_is_handler_mode(env);
|
||||||
|
spsel = env->v7m.control[M_REG_S] & R_V7M_CONTROL_SPSEL_MASK;
|
||||||
|
|
||||||
|
frame_sp_p = get_v7m_sp_ptr(env, true, threadmode, spsel);
|
||||||
|
frameptr = *frame_sp_p;
|
||||||
|
|
||||||
|
/* These loads may throw an exception (for MPU faults). We want to
|
||||||
|
* do them as secure, so work out what MMU index that is.
|
||||||
|
*/
|
||||||
|
mmu_idx = arm_v7m_mmu_idx_for_secstate(env, true);
|
||||||
|
oi = make_memop_idx(MO_LE, arm_to_core_mmu_idx(mmu_idx));
|
||||||
|
newpc = helper_le_ldul_mmu(env, frameptr, oi, 0);
|
||||||
|
newpsr = helper_le_ldul_mmu(env, frameptr + 4, oi, 0);
|
||||||
|
|
||||||
|
/* Consistency checks on new IPSR */
|
||||||
|
newpsr_exc = newpsr & XPSR_EXCP;
|
||||||
|
if (!((env->v7m.exception == 0 && newpsr_exc == 0) ||
|
||||||
|
(env->v7m.exception == 1 && newpsr_exc != 0))) {
|
||||||
|
/* Pend the fault and tell our caller to take it */
|
||||||
|
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
|
||||||
|
// Unicorn: commented out
|
||||||
|
//armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
|
||||||
|
// env->v7m.secure);
|
||||||
|
qemu_log_mask(CPU_LOG_INT,
|
||||||
|
"...taking INVPC UsageFault: "
|
||||||
|
"IPSR consistency check failed\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*frame_sp_p = frameptr + 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This invalidates frame_sp_p */
|
||||||
|
switch_v7m_security_state(env, true);
|
||||||
|
env->v7m.exception = newpsr_exc;
|
||||||
|
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
|
||||||
|
if (newpsr & XPSR_SFPA) {
|
||||||
|
env->v7m.control[M_REG_S] |= R_V7M_CONTROL_SFPA_MASK;
|
||||||
|
}
|
||||||
|
xpsr_write(env, 0, XPSR_IT);
|
||||||
|
env->thumb = newpc & 1;
|
||||||
|
env->regs[15] = newpc & ~1;
|
||||||
|
|
||||||
|
qemu_log_mask(CPU_LOG_INT, "...function return successful\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void arm_log_exception(int idx)
|
static void arm_log_exception(int idx)
|
||||||
{
|
{
|
||||||
if (qemu_loglevel_mask(CPU_LOG_INT)) {
|
if (qemu_loglevel_mask(CPU_LOG_INT)) {
|
||||||
|
@ -6780,8 +6853,18 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
|
||||||
case EXCP_IRQ:
|
case EXCP_IRQ:
|
||||||
break;
|
break;
|
||||||
case EXCP_EXCEPTION_EXIT:
|
case EXCP_EXCEPTION_EXIT:
|
||||||
|
if (env->regs[15] < EXC_RETURN_MIN_MAGIC) {
|
||||||
|
/* Must be v8M security extension function return */
|
||||||
|
assert(env->regs[15] >= FNC_RETURN_MIN_MAGIC);
|
||||||
|
assert(arm_feature(env, ARM_FEATURE_M_SECURITY));
|
||||||
|
if (do_v7m_function_return(cpu)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
do_v7m_exception_exit(cpu);
|
do_v7m_exception_exit(cpu);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
|
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
|
||||||
return; /* Never happens. Keep compiler happy. */
|
return; /* Never happens. Keep compiler happy. */
|
||||||
|
@ -7124,11 +7207,11 @@ static void arm_cpu_do_interrupt_aarch32_(CPUState *cs)
|
||||||
addr = 0x1c;
|
addr = 0x1c;
|
||||||
/* Disable FIQ, IRQ and imprecise data aborts. */
|
/* Disable FIQ, IRQ and imprecise data aborts. */
|
||||||
mask = CPSR_A | CPSR_I | CPSR_F;
|
mask = CPSR_A | CPSR_I | CPSR_F;
|
||||||
offset = 4;
|
|
||||||
if (env->cp15.scr_el3 & SCR_FIQ) {
|
if (env->cp15.scr_el3 & SCR_FIQ) {
|
||||||
/* FIQ routed to monitor mode */
|
/* FIQ routed to monitor mode */
|
||||||
new_mode = ARM_CPU_MODE_MON;
|
new_mode = ARM_CPU_MODE_MON;
|
||||||
}
|
}
|
||||||
|
offset = 4;
|
||||||
break;
|
break;
|
||||||
case EXCP_VIRQ:
|
case EXCP_VIRQ:
|
||||||
new_mode = ARM_CPU_MODE_IRQ;
|
new_mode = ARM_CPU_MODE_IRQ;
|
||||||
|
@ -7154,7 +7237,7 @@ static void arm_cpu_do_interrupt_aarch32_(CPUState *cs)
|
||||||
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
|
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
|
||||||
return; /* Never happens. Keep compiler happy. */
|
return; /* Never happens. Keep compiler happy. */
|
||||||
}
|
}
|
||||||
/* High vectors. */
|
|
||||||
if (new_mode == ARM_CPU_MODE_MON) {
|
if (new_mode == ARM_CPU_MODE_MON) {
|
||||||
addr += env->cp15.mvbar;
|
addr += env->cp15.mvbar;
|
||||||
} else if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) {
|
} else if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) {
|
||||||
|
@ -7186,7 +7269,7 @@ static void arm_cpu_do_interrupt_aarch32_(CPUState *cs)
|
||||||
/* Set new mode endianness */
|
/* Set new mode endianness */
|
||||||
env->uncached_cpsr &= ~CPSR_E;
|
env->uncached_cpsr &= ~CPSR_E;
|
||||||
if (env->cp15.sctlr_el[arm_current_el(env)] & SCTLR_EE) {
|
if (env->cp15.sctlr_el[arm_current_el(env)] & SCTLR_EE) {
|
||||||
env->uncached_cpsr |= ~CPSR_E;
|
env->uncached_cpsr |= CPSR_E;
|
||||||
}
|
}
|
||||||
env->daif |= mask;
|
env->daif |= mask;
|
||||||
/* this is a lie, as the was no c1_sys on V4T/V5, but who cares
|
/* this is a lie, as the was no c1_sys on V4T/V5, but who cares
|
||||||
|
@ -8390,7 +8473,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||||
* is unpredictable. Flag this as a guest error. */
|
* is unpredictable. Flag this as a guest error. */
|
||||||
if (sign != sext) {
|
if (sign != sext) {
|
||||||
qemu_log_mask(LOG_GUEST_ERROR,
|
qemu_log_mask(LOG_GUEST_ERROR,
|
||||||
"AArch32: VTCR.S / VTCR.T0SZ[3] missmatch\n");
|
"AArch32: VTCR.S / VTCR.T0SZ[3] mismatch\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t1sz = extract32(tcr->raw_tcr, 16, 6);
|
t1sz = extract32(tcr->raw_tcr, 16, 6);
|
||||||
|
@ -8537,6 +8620,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||||
if (fi->type != ARMFault_None) {
|
if (fi->type != ARMFault_None) {
|
||||||
goto do_fault;
|
goto do_fault;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(descriptor & 1) ||
|
if (!(descriptor & 1) ||
|
||||||
(!(descriptor & 2) && (level == 3))) {
|
(!(descriptor & 2) && (level == 3))) {
|
||||||
/* Invalid, or the Reserved level 3 encoding */
|
/* Invalid, or the Reserved level 3 encoding */
|
||||||
|
@ -8564,14 +8648,14 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||||
/* Extract attributes from the descriptor */
|
/* Extract attributes from the descriptor */
|
||||||
attrs = extract64(descriptor, 2, 10)
|
attrs = extract64(descriptor, 2, 10)
|
||||||
| (extract64(descriptor, 52, 12) << 10);
|
| (extract64(descriptor, 52, 12) << 10);
|
||||||
attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */
|
|
||||||
attrs |= extract32(tableattrs, 3, 1) << 5; /* APTable[1] => AP[2] */
|
|
||||||
|
|
||||||
if (mmu_idx == ARMMMUIdx_S2NS) {
|
if (mmu_idx == ARMMMUIdx_S2NS) {
|
||||||
/* Stage 2 table descriptors do not include any attribute fields */
|
/* Stage 2 table descriptors do not include any attribute fields */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Merge in attributes from table descriptors */
|
/* Merge in attributes from table descriptors */
|
||||||
|
attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */
|
||||||
|
attrs |= extract32(tableattrs, 3, 1) << 5; /* APTable[1] => AP[2] */
|
||||||
/* The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1
|
/* The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1
|
||||||
* means "force PL1 access only", which means forcing AP[1] to 0.
|
* means "force PL1 access only", which means forcing AP[1] to 0.
|
||||||
*/
|
*/
|
||||||
|
@ -8604,7 +8688,6 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||||
|
|
||||||
fault_type = ARMFault_Permission;
|
fault_type = ARMFault_Permission;
|
||||||
if (!(*prot & (1 << access_type))) {
|
if (!(*prot & (1 << access_type))) {
|
||||||
/* Unprivileged access not enabled */
|
|
||||||
goto do_fault;
|
goto do_fault;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8637,6 +8720,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||||
do_fault:
|
do_fault:
|
||||||
fi->type = fault_type;
|
fi->type = fault_type;
|
||||||
fi->level = level;
|
fi->level = level;
|
||||||
|
/* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */
|
||||||
|
fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_S2NS);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8985,7 +9070,6 @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
|
||||||
|
|
||||||
*phys_ptr = address;
|
*phys_ptr = address;
|
||||||
*prot = 0;
|
*prot = 0;
|
||||||
|
|
||||||
if (mregion) {
|
if (mregion) {
|
||||||
*mregion = -1;
|
*mregion = -1;
|
||||||
}
|
}
|
||||||
|
@ -9087,6 +9171,7 @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
|
||||||
return !(*prot & (1 << access_type));
|
return !(*prot & (1 << access_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
|
static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
|
||||||
MMUAccessType access_type, ARMMMUIdx mmu_idx,
|
MMUAccessType access_type, ARMMMUIdx mmu_idx,
|
||||||
hwaddr *phys_ptr, MemTxAttrs *txattrs,
|
hwaddr *phys_ptr, MemTxAttrs *txattrs,
|
||||||
|
@ -9171,7 +9256,6 @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
*phys_ptr = address;
|
*phys_ptr = address;
|
||||||
for (n = 7; n >= 0; n--) {
|
for (n = 7; n >= 0; n--) {
|
||||||
base = env->cp15.c6_region[n];
|
base = env->cp15.c6_region[n];
|
||||||
|
@ -9326,6 +9410,7 @@ static ARMCacheAttrs combine_cacheattrs(ARMCacheAttrs s1, ARMCacheAttrs s2)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* get_phys_addr - get the physical address for this virtual address
|
/* get_phys_addr - get the physical address for this virtual address
|
||||||
*
|
*
|
||||||
* Find the physical address corresponding to the given virtual address,
|
* Find the physical address corresponding to the given virtual address,
|
||||||
|
@ -9423,6 +9508,7 @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
|
||||||
if (arm_feature(env, ARM_FEATURE_PMSA)) {
|
if (arm_feature(env, ARM_FEATURE_PMSA)) {
|
||||||
bool ret;
|
bool ret;
|
||||||
*page_size = TARGET_PAGE_SIZE;
|
*page_size = TARGET_PAGE_SIZE;
|
||||||
|
|
||||||
if (arm_feature(env, ARM_FEATURE_V8)) {
|
if (arm_feature(env, ARM_FEATURE_V8)) {
|
||||||
/* PMSAv8 */
|
/* PMSAv8 */
|
||||||
ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
|
ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
|
||||||
|
@ -9647,7 +9733,6 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
|
||||||
return env->v7m.faultmask[env->v7m.secure];
|
return env->v7m.faultmask[env->v7m.secure];
|
||||||
default:
|
default:
|
||||||
bad_reg:
|
bad_reg:
|
||||||
/* ??? For debugging only. */
|
|
||||||
qemu_log_mask(LOG_GUEST_ERROR, "Attempt to read unknown special"
|
qemu_log_mask(LOG_GUEST_ERROR, "Attempt to read unknown special"
|
||||||
" register %d\n", reg);
|
" register %d\n", reg);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -10951,6 +11036,7 @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
|
||||||
/* The algorithm that must be used to calculate the estimate
|
/* The algorithm that must be used to calculate the estimate
|
||||||
* is specified by the ARM ARM.
|
* is specified by the ARM ARM.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int do_recip_sqrt_estimate(int a)
|
static int do_recip_sqrt_estimate(int a)
|
||||||
{
|
{
|
||||||
int b, estimate;
|
int b, estimate;
|
||||||
|
@ -10972,6 +11058,7 @@ static int do_recip_sqrt_estimate(int a)
|
||||||
return estimate;
|
return estimate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint64_t recip_sqrt_estimate(int *exp , int exp_off, uint64_t frac)
|
static uint64_t recip_sqrt_estimate(int *exp , int exp_off, uint64_t frac)
|
||||||
{
|
{
|
||||||
int estimate;
|
int estimate;
|
||||||
|
@ -10984,6 +11071,7 @@ static uint64_t recip_sqrt_estimate(int *exp , int exp_off, uint64_t frac)
|
||||||
}
|
}
|
||||||
frac = extract64(frac, 0, 51) << 1;
|
frac = extract64(frac, 0, 51) << 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*exp & 1) {
|
if (*exp & 1) {
|
||||||
/* scaled = UInt('01':fraction<51:45>) */
|
/* scaled = UInt('01':fraction<51:45>) */
|
||||||
scaled = deposit32(1 << 7, 0, 7, extract64(frac, 45, 7));
|
scaled = deposit32(1 << 7, 0, 7, extract64(frac, 45, 7));
|
||||||
|
|
Loading…
Reference in a new issue