diff options
author | j_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-03-31 11:10:49 +0000 |
---|---|---|
committer | j_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-03-31 11:10:49 +0000 |
commit | 1d0a48fb920cdd038aa1238740032e27aa460677 (patch) | |
tree | 4df06411d6404de0f012a4ba1ac54b1f47a5e60c /target-ppc | |
parent | 05a8096f2dd33234cacb957d2694281efc85e74d (diff) |
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
Diffstat (limited to 'target-ppc')
-rw-r--r-- | target-ppc/cpu.h | 20 | ||||
-rw-r--r-- | target-ppc/helper.c | 20 |
2 files changed, 26 insertions, 14 deletions
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 8d2c3a9562..7204abe028 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -528,7 +528,7 @@ typedef struct ppc_tb_t ppc_tb_t; typedef struct ppc_spr_t ppc_spr_t; typedef struct ppc_dcr_t ppc_dcr_t; typedef struct ppc_avr_t ppc_avr_t; -typedef struct ppc_tlb_t ppc_tlb_t; +typedef union ppc_tlb_t ppc_tlb_t; /* SPR access micro-ops generations callbacks */ struct ppc_spr_t { @@ -547,12 +547,26 @@ struct ppc_avr_t { }; /* Software TLB cache */ -struct ppc_tlb_t { +typedef struct ppc6xx_tlb_t ppc6xx_tlb_t; +struct ppc6xx_tlb_t { target_ulong pte0; target_ulong pte1; target_ulong EPN; +}; + +typedef struct ppcemb_tlb_t ppcemb_tlb_t; +struct ppcemb_tlb_t { + target_ulong RPN; + target_ulong EPN; target_ulong PID; int size; + int prot; + int attr; /* Storage attributes */ +}; + +union ppc_tlb_t { + ppc6xx_tlb_t tlb6; + ppcemb_tlb_t tlbe; }; /*****************************************************************************/ @@ -729,7 +743,7 @@ struct CPUPPCState { int nb_pids; /* Number of available PID registers */ ppc_tlb_t *tlb; /* TLB is optional. Allocate them only if needed */ /* Callbacks for specific checks on some implementations */ - int (*tlb_check_more)(CPUPPCState *env, struct ppc_tlb_t *tlb, int *prot, + int (*tlb_check_more)(CPUPPCState *env, ppc_tlb_t *tlb, int *prot, target_ulong vaddr, int rw, int acc_type, int is_user); /* 403 dedicated access protection registers */ diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 4356edc36c..c835b1efe8 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -186,7 +186,7 @@ static int ppc6xx_tlb_getnum (CPUState *env, target_ulong eaddr, void ppc6xx_tlb_invalidate_all (CPUState *env) { - ppc_tlb_t *tlb; + ppc6xx_tlb_t *tlb; int nr, max; #if defined (DEBUG_SOFTWARE_TLB) && 0 @@ -199,7 +199,7 @@ void ppc6xx_tlb_invalidate_all (CPUState *env) if (env->id_tlbs == 1) max *= 2; for (nr = 0; nr < max; nr++) { - tlb = &env->tlb[nr]; + tlb = &env->tlb[nr].tlb6; #if !defined(FLUSH_ALL_TLBS) tlb_flush_page(env, tlb->EPN); #endif @@ -214,14 +214,14 @@ static inline void __ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr, int is_code, int match_epn) { - ppc_tlb_t *tlb; + ppc6xx_tlb_t *tlb; int way, nr; #if !defined(FLUSH_ALL_TLBS) /* Invalidate ITLB + DTLB, all ways */ for (way = 0; way < env->nb_ways; way++) { nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code); - tlb = &env->tlb[nr]; + tlb = &env->tlb[nr].tlb6; if (pte_is_valid(tlb->pte0) && (match_epn == 0 || eaddr == tlb->EPN)) { #if defined (DEBUG_SOFTWARE_TLB) if (loglevel != 0) { @@ -248,11 +248,11 @@ void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr, void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code, target_ulong pte0, target_ulong pte1) { - ppc_tlb_t *tlb; + ppc6xx_tlb_t *tlb; int nr; nr = ppc6xx_tlb_getnum(env, EPN, way, is_code); - tlb = &env->tlb[nr]; + tlb = &env->tlb[nr].tlb6; #if defined (DEBUG_SOFTWARE_TLB) if (loglevel != 0) { 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, tlb->pte0 = pte0; tlb->pte1 = pte1; tlb->EPN = EPN; - tlb->PID = 0; - tlb->size = 1; /* Store last way for LRU mechanism */ env->last_way = way; } @@ -273,7 +271,7 @@ void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code, static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, int rw, int access_type) { - ppc_tlb_t *tlb; + ppc6xx_tlb_t *tlb; int nr, best, way; int ret; @@ -282,7 +280,7 @@ static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx, for (way = 0; way < env->nb_ways; way++) { nr = ppc6xx_tlb_getnum(env, eaddr, way, access_type == ACCESS_CODE ? 1 : 0); - tlb = &env->tlb[nr]; + tlb = &env->tlb[nr].tlb6; /* This test "emulates" the PTE index match for hardware TLBs */ if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) { #if defined (DEBUG_SOFTWARE_TLB) @@ -339,7 +337,7 @@ static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx, } #endif /* Update page flags */ - pte_update_flags(ctx, &env->tlb[best].pte1, ret, rw); + pte_update_flags(ctx, &env->tlb[best].tlb6.pte1, ret, rw); } return ret; |