Revision 1d0a48fb
b/target-ppc/cpu.h | ||
---|---|---|
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 | 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 | 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 */ |
b/target-ppc/helper.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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; |
Also available in: Unified diff