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 --- |