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 page_shift = 12;
|
||||||
target_ulong raddr;
|
target_ulong raddr;
|
||||||
target_ulong index;
|
target_ulong index;
|
||||||
hwaddr hpte;
|
|
||||||
uint64_t token;
|
uint64_t token;
|
||||||
|
|
||||||
/* only handle 4k and 16M pages for now */
|
/* only handle 4k and 16M pages for now */
|
||||||
|
@ -108,7 +107,6 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||||
}
|
}
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
hpte = pte_index * HASH_PTE_SIZE_64;
|
|
||||||
if (likely((flags & H_EXACT) == 0)) {
|
if (likely((flags & H_EXACT) == 0)) {
|
||||||
pte_index &= ~7ULL;
|
pte_index &= ~7ULL;
|
||||||
token = ppc_hash64_start_access(cpu, pte_index);
|
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);
|
ppc_hash64_stop_access(token);
|
||||||
}
|
}
|
||||||
hpte += index * HASH_PTE_SIZE_64;
|
|
||||||
|
|
||||||
ppc_hash64_store_hpte1(env, hpte, ptel);
|
ppc_hash64_store_hpte(env, pte_index + index,
|
||||||
/* eieio(); FIXME: need some sort of barrier for smp? */
|
pteh | HPTE64_V_HPTE_DIRTY, ptel);
|
||||||
ppc_hash64_store_hpte0(env, hpte, pteh | HPTE64_V_HPTE_DIRTY);
|
|
||||||
|
|
||||||
args[0] = pte_index + index;
|
args[0] = pte_index + index;
|
||||||
return H_SUCCESS;
|
return H_SUCCESS;
|
||||||
|
@ -152,7 +148,6 @@ static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex,
|
||||||
target_ulong flags,
|
target_ulong flags,
|
||||||
target_ulong *vp, target_ulong *rp)
|
target_ulong *vp, target_ulong *rp)
|
||||||
{
|
{
|
||||||
hwaddr hpte;
|
|
||||||
uint64_t token;
|
uint64_t token;
|
||||||
target_ulong v, r, rb;
|
target_ulong v, r, rb;
|
||||||
|
|
||||||
|
@ -172,8 +167,7 @@ static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex,
|
||||||
}
|
}
|
||||||
*vp = v;
|
*vp = v;
|
||||||
*rp = r;
|
*rp = r;
|
||||||
hpte = ptex * HASH_PTE_SIZE_64;
|
ppc_hash64_store_hpte(env, ptex, HPTE64_V_HPTE_DIRTY, 0);
|
||||||
ppc_hash64_store_hpte0(env, hpte, HPTE64_V_HPTE_DIRTY);
|
|
||||||
rb = compute_tlbie_rb(v, r, ptex);
|
rb = compute_tlbie_rb(v, r, ptex);
|
||||||
ppc_tlb_invalidate_one(env, rb);
|
ppc_tlb_invalidate_one(env, rb);
|
||||||
return REMOVE_SUCCESS;
|
return REMOVE_SUCCESS;
|
||||||
|
@ -280,7 +274,6 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||||
target_ulong flags = args[0];
|
target_ulong flags = args[0];
|
||||||
target_ulong pte_index = args[1];
|
target_ulong pte_index = args[1];
|
||||||
target_ulong avpn = args[2];
|
target_ulong avpn = args[2];
|
||||||
hwaddr hpte;
|
|
||||||
uint64_t token;
|
uint64_t token;
|
||||||
target_ulong v, r, rb;
|
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 << 48) & HPTE64_R_KEY_HI;
|
||||||
r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO);
|
r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO);
|
||||||
rb = compute_tlbie_rb(v, r, pte_index);
|
rb = compute_tlbie_rb(v, r, pte_index);
|
||||||
hpte = pte_index * HASH_PTE_SIZE_64;
|
ppc_hash64_store_hpte(env, pte_index,
|
||||||
ppc_hash64_store_hpte0(env, hpte, (v & ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY);
|
(v & ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY, 0);
|
||||||
ppc_tlb_invalidate_one(env, rb);
|
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 */
|
/* 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;
|
return H_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -566,7 +566,8 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_pte1 != pte.pte1) {
|
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 */
|
/* 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,
|
static inline void ppc_hash64_store_hpte(CPUPPCState *env,
|
||||||
hwaddr pte_offset, target_ulong pte0)
|
target_ulong pte_index,
|
||||||
|
target_ulong pte0, target_ulong pte1)
|
||||||
{
|
{
|
||||||
CPUState *cs = ENV_GET_CPU(env);
|
CPUState *cs = ENV_GET_CPU(env);
|
||||||
|
pte_index *= HASH_PTE_SIZE_64;
|
||||||
if (env->external_htab) {
|
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 {
|
} else {
|
||||||
stq_phys(cs->as, env->htab_base + pte_offset, pte0);
|
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);
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue