Commit 1d0a48fb920cdd038aa1238740032e27aa460677
1 parent
05a8096f
As embedded PowerPC TLB model is very different from PowerPC 6xx ones,
define ppc_tlb_t as an union of the two. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2553 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
26 additions
and
14 deletions
target-ppc/cpu.h
| ... | ... | @@ -528,7 +528,7 @@ typedef struct ppc_tb_t ppc_tb_t; |
| 528 | 528 | typedef struct ppc_spr_t ppc_spr_t; |
| 529 | 529 | typedef struct ppc_dcr_t ppc_dcr_t; |
| 530 | 530 | typedef struct ppc_avr_t ppc_avr_t; |
| 531 | -typedef struct ppc_tlb_t ppc_tlb_t; | |
| 531 | +typedef union ppc_tlb_t ppc_tlb_t; | |
| 532 | 532 | |
| 533 | 533 | /* SPR access micro-ops generations callbacks */ |
| 534 | 534 | struct ppc_spr_t { |
| ... | ... | @@ -547,12 +547,26 @@ struct ppc_avr_t { |
| 547 | 547 | }; |
| 548 | 548 | |
| 549 | 549 | /* Software TLB cache */ |
| 550 | -struct ppc_tlb_t { | |
| 550 | +typedef struct ppc6xx_tlb_t ppc6xx_tlb_t; | |
| 551 | +struct ppc6xx_tlb_t { | |
| 551 | 552 | target_ulong pte0; |
| 552 | 553 | target_ulong pte1; |
| 553 | 554 | target_ulong EPN; |
| 555 | +}; | |
| 556 | + | |
| 557 | +typedef struct ppcemb_tlb_t ppcemb_tlb_t; | |
| 558 | +struct ppcemb_tlb_t { | |
| 559 | + target_ulong RPN; | |
| 560 | + target_ulong EPN; | |
| 554 | 561 | target_ulong PID; |
| 555 | 562 | int size; |
| 563 | + int prot; | |
| 564 | + int attr; /* Storage attributes */ | |
| 565 | +}; | |
| 566 | + | |
| 567 | +union ppc_tlb_t { | |
| 568 | + ppc6xx_tlb_t tlb6; | |
| 569 | + ppcemb_tlb_t tlbe; | |
| 556 | 570 | }; |
| 557 | 571 | |
| 558 | 572 | /*****************************************************************************/ |
| ... | ... | @@ -729,7 +743,7 @@ struct CPUPPCState { |
| 729 | 743 | int nb_pids; /* Number of available PID registers */ |
| 730 | 744 | ppc_tlb_t *tlb; /* TLB is optional. Allocate them only if needed */ |
| 731 | 745 | /* Callbacks for specific checks on some implementations */ |
| 732 | - int (*tlb_check_more)(CPUPPCState *env, struct ppc_tlb_t *tlb, int *prot, | |
| 746 | + int (*tlb_check_more)(CPUPPCState *env, ppc_tlb_t *tlb, int *prot, | |
| 733 | 747 | target_ulong vaddr, int rw, int acc_type, |
| 734 | 748 | int is_user); |
| 735 | 749 | /* 403 dedicated access protection registers */ | ... | ... |
target-ppc/helper.c
| ... | ... | @@ -186,7 +186,7 @@ static int ppc6xx_tlb_getnum (CPUState *env, target_ulong eaddr, |
| 186 | 186 | |
| 187 | 187 | void ppc6xx_tlb_invalidate_all (CPUState *env) |
| 188 | 188 | { |
| 189 | - ppc_tlb_t *tlb; | |
| 189 | + ppc6xx_tlb_t *tlb; | |
| 190 | 190 | int nr, max; |
| 191 | 191 | |
| 192 | 192 | #if defined (DEBUG_SOFTWARE_TLB) && 0 |
| ... | ... | @@ -199,7 +199,7 @@ void ppc6xx_tlb_invalidate_all (CPUState *env) |
| 199 | 199 | if (env->id_tlbs == 1) |
| 200 | 200 | max *= 2; |
| 201 | 201 | for (nr = 0; nr < max; nr++) { |
| 202 | - tlb = &env->tlb[nr]; | |
| 202 | + tlb = &env->tlb[nr].tlb6; | |
| 203 | 203 | #if !defined(FLUSH_ALL_TLBS) |
| 204 | 204 | tlb_flush_page(env, tlb->EPN); |
| 205 | 205 | #endif |
| ... | ... | @@ -214,14 +214,14 @@ static inline void __ppc6xx_tlb_invalidate_virt (CPUState *env, |
| 214 | 214 | target_ulong eaddr, |
| 215 | 215 | int is_code, int match_epn) |
| 216 | 216 | { |
| 217 | - ppc_tlb_t *tlb; | |
| 217 | + ppc6xx_tlb_t *tlb; | |
| 218 | 218 | int way, nr; |
| 219 | 219 | |
| 220 | 220 | #if !defined(FLUSH_ALL_TLBS) |
| 221 | 221 | /* Invalidate ITLB + DTLB, all ways */ |
| 222 | 222 | for (way = 0; way < env->nb_ways; way++) { |
| 223 | 223 | nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code); |
| 224 | - tlb = &env->tlb[nr]; | |
| 224 | + tlb = &env->tlb[nr].tlb6; | |
| 225 | 225 | if (pte_is_valid(tlb->pte0) && (match_epn == 0 || eaddr == tlb->EPN)) { |
| 226 | 226 | #if defined (DEBUG_SOFTWARE_TLB) |
| 227 | 227 | if (loglevel != 0) { |
| ... | ... | @@ -248,11 +248,11 @@ void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr, |
| 248 | 248 | void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code, |
| 249 | 249 | target_ulong pte0, target_ulong pte1) |
| 250 | 250 | { |
| 251 | - ppc_tlb_t *tlb; | |
| 251 | + ppc6xx_tlb_t *tlb; | |
| 252 | 252 | int nr; |
| 253 | 253 | |
| 254 | 254 | nr = ppc6xx_tlb_getnum(env, EPN, way, is_code); |
| 255 | - tlb = &env->tlb[nr]; | |
| 255 | + tlb = &env->tlb[nr].tlb6; | |
| 256 | 256 | #if defined (DEBUG_SOFTWARE_TLB) |
| 257 | 257 | if (loglevel != 0) { |
| 258 | 258 | fprintf(logfile, "Set TLB %d/%d EPN " ADDRX " PTE0 " ADDRX |
| ... | ... | @@ -264,8 +264,6 @@ void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code, |
| 264 | 264 | tlb->pte0 = pte0; |
| 265 | 265 | tlb->pte1 = pte1; |
| 266 | 266 | tlb->EPN = EPN; |
| 267 | - tlb->PID = 0; | |
| 268 | - tlb->size = 1; | |
| 269 | 267 | /* Store last way for LRU mechanism */ |
| 270 | 268 | env->last_way = way; |
| 271 | 269 | } |
| ... | ... | @@ -273,7 +271,7 @@ void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code, |
| 273 | 271 | static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx, |
| 274 | 272 | target_ulong eaddr, int rw, int access_type) |
| 275 | 273 | { |
| 276 | - ppc_tlb_t *tlb; | |
| 274 | + ppc6xx_tlb_t *tlb; | |
| 277 | 275 | int nr, best, way; |
| 278 | 276 | int ret; |
| 279 | 277 | |
| ... | ... | @@ -282,7 +280,7 @@ static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx, |
| 282 | 280 | for (way = 0; way < env->nb_ways; way++) { |
| 283 | 281 | nr = ppc6xx_tlb_getnum(env, eaddr, way, |
| 284 | 282 | access_type == ACCESS_CODE ? 1 : 0); |
| 285 | - tlb = &env->tlb[nr]; | |
| 283 | + tlb = &env->tlb[nr].tlb6; | |
| 286 | 284 | /* This test "emulates" the PTE index match for hardware TLBs */ |
| 287 | 285 | if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) { |
| 288 | 286 | #if defined (DEBUG_SOFTWARE_TLB) |
| ... | ... | @@ -339,7 +337,7 @@ static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx, |
| 339 | 337 | } |
| 340 | 338 | #endif |
| 341 | 339 | /* Update page flags */ |
| 342 | - pte_update_flags(ctx, &env->tlb[best].pte1, ret, rw); | |
| 340 | + pte_update_flags(ctx, &env->tlb[best].tlb6.pte1, ret, rw); | |
| 343 | 341 | } |
| 344 | 342 | |
| 345 | 343 | return ret; | ... | ... |