mmu_common.c (f1418bdeb09d201ea636d061fa6edf1175074a09) mmu_common.c (0af20f35d254bc87689a9d5ab2c5e45a677467dc)
1/*
2 * PowerPC MMU, TLB, SLB and BAT emulation helpers for QEMU.
3 *
4 * Copyright (c) 2003-2007 Jocelyn Mayer
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either

--- 211 unchanged lines hidden (view full) ---

220 TARGET_FMT_lx " " TARGET_FMT_lx " %c %c\n",
221 nr, env->nb_tlb,
222 pte_is_valid(tlb->pte0) ? "valid" : "inval",
223 tlb->EPN, eaddr, tlb->pte1,
224 access_type == MMU_DATA_STORE ? 'S' : 'L',
225 access_type == MMU_INST_FETCH ? 'I' : 'D');
226 switch (ppc6xx_tlb_pte_check(ctx, tlb->pte0, tlb->pte1,
227 0, access_type)) {
1/*
2 * PowerPC MMU, TLB, SLB and BAT emulation helpers for QEMU.
3 *
4 * Copyright (c) 2003-2007 Jocelyn Mayer
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either

--- 211 unchanged lines hidden (view full) ---

220 TARGET_FMT_lx " " TARGET_FMT_lx " %c %c\n",
221 nr, env->nb_tlb,
222 pte_is_valid(tlb->pte0) ? "valid" : "inval",
223 tlb->EPN, eaddr, tlb->pte1,
224 access_type == MMU_DATA_STORE ? 'S' : 'L',
225 access_type == MMU_INST_FETCH ? 'I' : 'D');
226 switch (ppc6xx_tlb_pte_check(ctx, tlb->pte0, tlb->pte1,
227 0, access_type)) {
228 case -3:
229 /* TLB inconsistency */
230 return -1;
231 case -2:
232 /* Access violation */
233 ret = -2;
234 best = nr;
235 break;
228 case -2:
229 /* Access violation */
230 ret = -2;
231 best = nr;
232 break;
236 case -1:
233 case -1: /* No match */
234 case -3: /* TLB inconsistency */
237 default:
235 default:
238 /* No match */
239 break;
240 case 0:
241 /* access granted */
242 /*
243 * XXX: we should go on looping to check all TLBs
244 * consistency but we can speed-up the whole thing as
245 * the result would be undefined if TLBs are not
246 * consistent.
247 */
248 ret = 0;
249 best = nr;
250 goto done;
251 }
252 }
253 if (best != -1) {
236 break;
237 case 0:
238 /* access granted */
239 /*
240 * XXX: we should go on looping to check all TLBs
241 * consistency but we can speed-up the whole thing as
242 * the result would be undefined if TLBs are not
243 * consistent.
244 */
245 ret = 0;
246 best = nr;
247 goto done;
248 }
249 }
250 if (best != -1) {
254 done:
251done:
255 qemu_log_mask(CPU_LOG_MMU, "found TLB at addr " HWADDR_FMT_plx
256 " prot=%01x ret=%d\n",
257 ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
258 /* Update page flags */
259 pte_update_flags(ctx, &env->tlb.tlb6[best].pte1, ret, access_type);
260 }
252 qemu_log_mask(CPU_LOG_MMU, "found TLB at addr " HWADDR_FMT_plx
253 " prot=%01x ret=%d\n",
254 ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
255 /* Update page flags */
256 pte_update_flags(ctx, &env->tlb.tlb6[best].pte1, ret, access_type);
257 }
258#if defined(DUMP_PAGE_TABLES)
259 if (qemu_loglevel_mask(CPU_LOG_MMU)) {
260 CPUState *cs = env_cpu(env);
261 hwaddr base = ppc_hash32_hpt_base(env_archcpu(env));
262 hwaddr len = ppc_hash32_hpt_mask(env_archcpu(env)) + 0x80;
263 uint32_t a0, a1, a2, a3;
261
264
265 qemu_log("Page table: " HWADDR_FMT_plx " len " HWADDR_FMT_plx "\n",
266 base, len);
267 for (hwaddr curaddr = base; curaddr < base + len; curaddr += 16) {
268 a0 = ldl_phys(cs->as, curaddr);
269 a1 = ldl_phys(cs->as, curaddr + 4);
270 a2 = ldl_phys(cs->as, curaddr + 8);
271 a3 = ldl_phys(cs->as, curaddr + 12);
272 if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
273 qemu_log(HWADDR_FMT_plx ": %08x %08x %08x %08x\n",
274 curaddr, a0, a1, a2, a3);
275 }
276 }
277 }
278#endif
262 return ret;
263}
264
265/* Perform BAT hit & translation */
266static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp,
267 int *validp, int *protp, target_ulong *BATu,
268 target_ulong *BATl)
269{

--- 145 unchanged lines hidden (view full) ---

415 ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash);
416 ctx->hash[0] = hash;
417 ctx->hash[1] = ~hash;
418
419 /* Initialize real address with an invalid value */
420 ctx->raddr = (hwaddr)-1ULL;
421 /* Software TLB search */
422 ret = ppc6xx_tlb_check(env, ctx, eaddr, access_type);
279 return ret;
280}
281
282/* Perform BAT hit & translation */
283static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp,
284 int *validp, int *protp, target_ulong *BATu,
285 target_ulong *BATl)
286{

--- 145 unchanged lines hidden (view full) ---

432 ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu), hash);
433 ctx->hash[0] = hash;
434 ctx->hash[1] = ~hash;
435
436 /* Initialize real address with an invalid value */
437 ctx->raddr = (hwaddr)-1ULL;
438 /* Software TLB search */
439 ret = ppc6xx_tlb_check(env, ctx, eaddr, access_type);
423#if defined(DUMP_PAGE_TABLES)
424 if (qemu_loglevel_mask(CPU_LOG_MMU)) {
425 CPUState *cs = env_cpu(env);
426 hwaddr curaddr;
427 uint32_t a0, a1, a2, a3;
428
429 qemu_log("Page table: " HWADDR_FMT_plx " len " HWADDR_FMT_plx "\n",
430 ppc_hash32_hpt_base(cpu), ppc_hash32_hpt_mask(cpu) + 0x80);
431 for (curaddr = ppc_hash32_hpt_base(cpu);
432 curaddr < (ppc_hash32_hpt_base(cpu)
433 + ppc_hash32_hpt_mask(cpu) + 0x80);
434 curaddr += 16) {
435 a0 = ldl_phys(cs->as, curaddr);
436 a1 = ldl_phys(cs->as, curaddr + 4);
437 a2 = ldl_phys(cs->as, curaddr + 8);
438 a3 = ldl_phys(cs->as, curaddr + 12);
439 if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
440 qemu_log(HWADDR_FMT_plx ": %08x %08x %08x %08x\n",
441 curaddr, a0, a1, a2, a3);
442 }
443 }
444 }
445#endif
446 } else {
447 qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
448 /* Direct-store segment : absolutely *BUGGY* for now */
449
450 switch (type) {
451 case ACCESS_INT:
452 /* Integer load/store : only access allowed */
453 break;

--- 1101 unchanged lines hidden ---
440 } else {
441 qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
442 /* Direct-store segment : absolutely *BUGGY* for now */
443
444 switch (type) {
445 case ACCESS_INT:
446 /* Integer load/store : only access allowed */
447 break;

--- 1101 unchanged lines hidden ---