mirror of https://gitee.com/openkylin/qemu.git
target-ppc: Change the hpte store API
For updating in kernel htab we need to provide both pte0 and pte1, hence update the interface to take pte0 and pte1 together Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> [ ldq_phys() API change, Greg Kurz <gkurz@linux.vnet.ibm.com> ] Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
7c43bca004
commit
3f94170be3
|
@ -62,7 +62,6 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
|||
target_ulong page_shift = 12;
|
||||
target_ulong raddr;
|
||||
target_ulong index;
|
||||
hwaddr hpte;
|
||||
uint64_t token;
|
||||
|
||||
/* only handle 4k and 16M pages for now */
|
||||
|
@ -108,7 +107,6 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
|||
}
|
||||
|
||||
index = 0;
|
||||
hpte = pte_index * HASH_PTE_SIZE_64;
|
||||
if (likely((flags & H_EXACT) == 0)) {
|
||||
pte_index &= ~7ULL;
|
||||
token = ppc_hash64_start_access(cpu, pte_index);
|
||||
|
@ -130,11 +128,9 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
|||
}
|
||||
ppc_hash64_stop_access(token);
|
||||
}
|
||||
hpte += index * HASH_PTE_SIZE_64;
|
||||
|
||||
ppc_hash64_store_hpte1(env, hpte, ptel);
|
||||
/* eieio(); FIXME: need some sort of barrier for smp? */
|
||||
ppc_hash64_store_hpte0(env, hpte, pteh | HPTE64_V_HPTE_DIRTY);
|
||||
ppc_hash64_store_hpte(env, pte_index + index,
|
||||
pteh | HPTE64_V_HPTE_DIRTY, ptel);
|
||||
|
||||
args[0] = pte_index + index;
|
||||
return H_SUCCESS;
|
||||
|
@ -152,7 +148,6 @@ static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex,
|
|||
target_ulong flags,
|
||||
target_ulong *vp, target_ulong *rp)
|
||||
{
|
||||
hwaddr hpte;
|
||||
uint64_t token;
|
||||
target_ulong v, r, rb;
|
||||
|
||||
|
@ -172,8 +167,7 @@ static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex,
|
|||
}
|
||||
*vp = v;
|
||||
*rp = r;
|
||||
hpte = ptex * HASH_PTE_SIZE_64;
|
||||
ppc_hash64_store_hpte0(env, hpte, HPTE64_V_HPTE_DIRTY);
|
||||
ppc_hash64_store_hpte(env, ptex, HPTE64_V_HPTE_DIRTY, 0);
|
||||
rb = compute_tlbie_rb(v, r, ptex);
|
||||
ppc_tlb_invalidate_one(env, rb);
|
||||
return REMOVE_SUCCESS;
|
||||
|
@ -280,7 +274,6 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
|||
target_ulong flags = args[0];
|
||||
target_ulong pte_index = args[1];
|
||||
target_ulong avpn = args[2];
|
||||
hwaddr hpte;
|
||||
uint64_t token;
|
||||
target_ulong v, r, rb;
|
||||
|
||||
|
@ -304,12 +297,11 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
|||
r |= (flags << 48) & HPTE64_R_KEY_HI;
|
||||
r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO);
|
||||
rb = compute_tlbie_rb(v, r, pte_index);
|
||||
hpte = pte_index * HASH_PTE_SIZE_64;
|
||||
ppc_hash64_store_hpte0(env, hpte, (v & ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY);
|
||||
ppc_hash64_store_hpte(env, pte_index,
|
||||
(v & ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY, 0);
|
||||
ppc_tlb_invalidate_one(env, rb);
|
||||
ppc_hash64_store_hpte1(env, hpte, r);
|
||||
/* Don't need a memory barrier, due to qemu's global lock */
|
||||
ppc_hash64_store_hpte0(env, hpte, v | HPTE64_V_HPTE_DIRTY);
|
||||
ppc_hash64_store_hpte(env, pte_index, v | HPTE64_V_HPTE_DIRTY, r);
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -566,7 +566,8 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
|
|||
}
|
||||
|
||||
if (new_pte1 != pte.pte1) {
|
||||
ppc_hash64_store_hpte1(env, pte_offset, new_pte1);
|
||||
ppc_hash64_store_hpte(env, pte_offset / HASH_PTE_SIZE_64,
|
||||
pte.pte0, new_pte1);
|
||||
}
|
||||
|
||||
/* 7. Determine the real address from the PTE */
|
||||
|
|
|
@ -106,26 +106,18 @@ static inline target_ulong ppc_hash64_load_hpte1(CPUPPCState *env,
|
|||
}
|
||||
}
|
||||
|
||||
static inline void ppc_hash64_store_hpte0(CPUPPCState *env,
|
||||
hwaddr pte_offset, target_ulong pte0)
|
||||
static inline void ppc_hash64_store_hpte(CPUPPCState *env,
|
||||
target_ulong pte_index,
|
||||
target_ulong pte0, target_ulong pte1)
|
||||
{
|
||||
CPUState *cs = ENV_GET_CPU(env);
|
||||
pte_index *= HASH_PTE_SIZE_64;
|
||||
if (env->external_htab) {
|
||||
stq_p(env->external_htab + pte_offset, pte0);
|
||||
stq_p(env->external_htab + pte_index, pte0);
|
||||
stq_p(env->external_htab + pte_index + HASH_PTE_SIZE_64/2, pte1);
|
||||
} else {
|
||||
stq_phys(cs->as, env->htab_base + pte_offset, pte0);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ppc_hash64_store_hpte1(CPUPPCState *env,
|
||||
hwaddr pte_offset, target_ulong pte1)
|
||||
{
|
||||
CPUState *cs = ENV_GET_CPU(env);
|
||||
if (env->external_htab) {
|
||||
stq_p(env->external_htab + pte_offset + HASH_PTE_SIZE_64/2, pte1);
|
||||
} else {
|
||||
stq_phys(cs->as,
|
||||
env->htab_base + pte_offset + HASH_PTE_SIZE_64/2, pte1);
|
||||
stq_phys(cs->as, env->htab_base + pte_index, pte0);
|
||||
stq_phys(cs->as, env->htab_base + pte_index + HASH_PTE_SIZE_64/2, pte1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue