target_ulong page_shift = 12;
target_ulong raddr;
target_ulong i;
- uint8_t *hpte;
+ hwaddr hpte;
/* only handle 4k and 16M pages for now */
if (pteh & HPTE64_V_LARGE) {
}
if (likely((flags & H_EXACT) == 0)) {
pte_index &= ~7ULL;
- hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
+ hpte = pte_index * HASH_PTE_SIZE_64;
for (i = 0; ; ++i) {
if (i == 8) {
return H_PTEG_FULL;
}
- if ((ldq_p(hpte) & HPTE64_V_VALID) == 0) {
+ if ((ppc_hash64_load_hpte0(env, hpte) & HPTE64_V_VALID) == 0) {
break;
}
hpte += HASH_PTE_SIZE_64;
}
} else {
i = 0;
- hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
- if (ldq_p(hpte) & HPTE64_V_VALID) {
+ hpte = pte_index * HASH_PTE_SIZE_64;
+ if (ppc_hash64_load_hpte0(env, hpte) & HPTE64_V_VALID) {
return H_PTEG_FULL;
}
}
- stq_p(hpte + (HASH_PTE_SIZE_64/2), ptel);
+ ppc_hash64_store_hpte1(env, hpte, ptel);
/* eieio(); FIXME: need some sort of barrier for smp? */
- stq_p(hpte, pteh);
+ ppc_hash64_store_hpte0(env, hpte, pteh);
args[0] = pte_index + i;
return H_SUCCESS;
target_ulong flags,
target_ulong *vp, target_ulong *rp)
{
- uint8_t *hpte;
+ hwaddr hpte;
target_ulong v, r, rb;
if ((ptex * HASH_PTE_SIZE_64) & ~env->htab_mask) {
return REMOVE_PARM;
}
- hpte = env->external_htab + (ptex * HASH_PTE_SIZE_64);
+ hpte = ptex * HASH_PTE_SIZE_64;
- v = ldq_p(hpte);
- r = ldq_p(hpte + (HASH_PTE_SIZE_64/2));
+ v = ppc_hash64_load_hpte0(env, hpte);
+ r = ppc_hash64_load_hpte1(env, hpte);
if ((v & HPTE64_V_VALID) == 0 ||
((flags & H_AVPN) && (v & ~0x7fULL) != avpn) ||
}
*vp = v;
*rp = r;
- stq_p(hpte, 0);
+ ppc_hash64_store_hpte0(env, hpte, 0);
rb = compute_tlbie_rb(v, r, ptex);
ppc_tlb_invalidate_one(env, rb);
return REMOVE_SUCCESS;
target_ulong flags = args[0];
target_ulong pte_index = args[1];
target_ulong avpn = args[2];
- uint8_t *hpte;
+ hwaddr hpte;
target_ulong v, r, rb;
if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {
return H_PARAMETER;
}
- hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
+ hpte = pte_index * HASH_PTE_SIZE_64;
- v = ldq_p(hpte);
- r = ldq_p(hpte + (HASH_PTE_SIZE_64/2));
+ v = ppc_hash64_load_hpte0(env, hpte);
+ r = ppc_hash64_load_hpte1(env, hpte);
if ((v & HPTE64_V_VALID) == 0 ||
((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) {
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);
- stq_p(hpte, v & ~HPTE64_V_VALID);
+ ppc_hash64_store_hpte0(env, hpte, v & ~HPTE64_V_VALID);
ppc_tlb_invalidate_one(env, rb);
- stq_p(hpte + (HASH_PTE_SIZE_64/2), r);
+ ppc_hash64_store_hpte1(env, hpte, r);
/* Don't need a memory barrier, due to qemu's global lock */
- stq_p(hpte, v);
+ ppc_hash64_store_hpte0(env, hpte, v);
return H_SUCCESS;
}
ret = -1; /* No entry found */
pteg_off = get_pteg_offset32(env, ctx->hash[h]);
for (i = 0; i < HPTES_PER_GROUP; i++) {
- if (env->external_htab) {
- pte0 = ldl_p(env->external_htab + pteg_off + (i * 8));
- pte1 = ldl_p(env->external_htab + pteg_off + (i * 8) + 4);
- } else {
- pte0 = ldl_phys(env->htab_base + pteg_off + (i * 8));
- pte1 = ldl_phys(env->htab_base + pteg_off + (i * 8) + 4);
- }
+ pte0 = ppc_hash32_load_hpte0(env, pteg_off + i*HASH_PTE_SIZE_32);
+ pte1 = ppc_hash32_load_hpte1(env, pteg_off + i*HASH_PTE_SIZE_32);
r = pte_check_hash32(ctx, pte0, pte1, h, rw, type);
LOG_MMU("Load pte from %08" HWADDR_PRIx " => " TARGET_FMT_lx " "
TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
/* Update page flags */
pte1 = ctx->raddr;
if (ppc_hash32_pte_update_flags(ctx, &pte1, ret, rw) == 1) {
- if (env->external_htab) {
- stl_p(env->external_htab + pteg_off + (good * 8) + 4,
- pte1);
- } else {
- stl_phys_notdirty(env->htab_base + pteg_off +
- (good * 8) + 4, pte1);
- }
+ ppc_hash32_store_hpte1(env, pteg_off + good * HASH_PTE_SIZE_32,
+ pte1);
}
}
#define HPTE32_R_WIMG 0x00000078
#define HPTE32_R_PP 0x00000003
+static inline target_ulong ppc_hash32_load_hpte0(CPUPPCState *env,
+ hwaddr pte_offset)
+{
+ assert(!env->external_htab); /* Not supported on 32-bit for now */
+ return ldl_phys(env->htab_base + pte_offset);
+}
+
+static inline target_ulong ppc_hash32_load_hpte1(CPUPPCState *env,
+ hwaddr pte_offset)
+{
+ assert(!env->external_htab); /* Not supported on 32-bit for now */
+ return ldl_phys(env->htab_base + pte_offset + HASH_PTE_SIZE_32/2);
+}
+
+static inline void ppc_hash32_store_hpte0(CPUPPCState *env,
+ hwaddr pte_offset, target_ulong pte0)
+{
+ assert(!env->external_htab); /* Not supported on 32-bit for now */
+ stl_phys(env->htab_base + pte_offset, pte0);
+}
+
+static inline void ppc_hash32_store_hpte1(CPUPPCState *env,
+ hwaddr pte_offset, target_ulong pte1)
+{
+ assert(!env->external_htab); /* Not supported on 32-bit for now */
+ stl_phys(env->htab_base + pte_offset + HASH_PTE_SIZE_32/2, pte1);
+}
+
#endif /* CONFIG_USER_ONLY */
#endif /* __MMU_HASH32_H__ */
ret = -1; /* No entry found */
pteg_off = (ctx->hash[h] * HASH_PTEG_SIZE_64) & env->htab_mask;
for (i = 0; i < HPTES_PER_GROUP; i++) {
- if (env->external_htab) {
- pte0 = ldq_p(env->external_htab + pteg_off + (i * 16));
- pte1 = ldq_p(env->external_htab + pteg_off + (i * 16) + 8);
- } else {
- pte0 = ldq_phys(env->htab_base + pteg_off + (i * 16));
- pte1 = ldq_phys(env->htab_base + pteg_off + (i * 16) + 8);
- }
+ pte0 = ppc_hash64_load_hpte0(env, pteg_off + i*HASH_PTE_SIZE_64);
+ pte1 = ppc_hash64_load_hpte1(env, pteg_off + i*HASH_PTE_SIZE_64);
r = pte64_check(ctx, pte0, pte1, h, rw, type);
LOG_MMU("Load pte from %016" HWADDR_PRIx " => " TARGET_FMT_lx " "
/* Update page flags */
pte1 = ctx->raddr;
if (ppc_hash64_pte_update_flags(ctx, &pte1, ret, rw) == 1) {
- if (env->external_htab) {
- stq_p(env->external_htab + pteg_off + (good * 16) + 8,
- pte1);
- } else {
- stq_phys_notdirty(env->htab_base + pteg_off +
- (good * 16) + 8, pte1);
- }
+ ppc_hash64_store_hpte1(env, pteg_off + good * HASH_PTE_SIZE_64, pte1);
}
}
#define HPTE64_V_1TB_SEG 0x4000000000000000ULL
#define HPTE64_V_VRMA_MASK 0x4001ffffff000000ULL
+static inline target_ulong ppc_hash64_load_hpte0(CPUPPCState *env,
+ hwaddr pte_offset)
+{
+ if (env->external_htab) {
+ return ldq_p(env->external_htab + pte_offset);
+ } else {
+ return ldq_phys(env->htab_base + pte_offset);
+ }
+}
+
+static inline target_ulong ppc_hash64_load_hpte1(CPUPPCState *env,
+ hwaddr pte_offset)
+{
+ if (env->external_htab) {
+ return ldq_p(env->external_htab + pte_offset + HASH_PTE_SIZE_64/2);
+ } else {
+ return ldq_phys(env->htab_base + pte_offset + HASH_PTE_SIZE_64/2);
+ }
+}
+
+static inline void ppc_hash64_store_hpte0(CPUPPCState *env,
+ hwaddr pte_offset, target_ulong pte0)
+{
+ if (env->external_htab) {
+ stq_p(env->external_htab + pte_offset, pte0);
+ } else {
+ stq_phys(env->htab_base + pte_offset, pte0);
+ }
+}
+
+static inline void ppc_hash64_store_hpte1(CPUPPCState *env,
+ hwaddr pte_offset, target_ulong pte1)
+{
+ if (env->external_htab) {
+ stq_p(env->external_htab + pte_offset + HASH_PTE_SIZE_64/2, pte1);
+ } else {
+ stq_phys(env->htab_base + pte_offset + HASH_PTE_SIZE_64/2, pte1);
+ }
+}
+
#endif /* CONFIG_USER_ONLY */
#endif /* !defined (__MMU_HASH64_H__) */