提交 1d0a48fb 编写于 作者: J j_mayer

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
上级 05a8096f
...@@ -528,7 +528,7 @@ typedef struct ppc_tb_t ppc_tb_t; ...@@ -528,7 +528,7 @@ typedef struct ppc_tb_t ppc_tb_t;
typedef struct ppc_spr_t ppc_spr_t; typedef struct ppc_spr_t ppc_spr_t;
typedef struct ppc_dcr_t ppc_dcr_t; typedef struct ppc_dcr_t ppc_dcr_t;
typedef struct ppc_avr_t ppc_avr_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 */ /* SPR access micro-ops generations callbacks */
struct ppc_spr_t { struct ppc_spr_t {
...@@ -547,12 +547,26 @@ struct ppc_avr_t { ...@@ -547,12 +547,26 @@ struct ppc_avr_t {
}; };
/* Software TLB cache */ /* Software TLB cache */
struct ppc_tlb_t { typedef struct ppc6xx_tlb_t ppc6xx_tlb_t;
struct ppc6xx_tlb_t {
target_ulong pte0; target_ulong pte0;
target_ulong pte1; target_ulong pte1;
target_ulong EPN; target_ulong EPN;
};
typedef struct ppcemb_tlb_t ppcemb_tlb_t;
struct ppcemb_tlb_t {
target_ulong RPN;
target_ulong EPN;
target_ulong PID; target_ulong PID;
int size; 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 { ...@@ -729,7 +743,7 @@ struct CPUPPCState {
int nb_pids; /* Number of available PID registers */ int nb_pids; /* Number of available PID registers */
ppc_tlb_t *tlb; /* TLB is optional. Allocate them only if needed */ ppc_tlb_t *tlb; /* TLB is optional. Allocate them only if needed */
/* Callbacks for specific checks on some implementations */ /* 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, target_ulong vaddr, int rw, int acc_type,
int is_user); int is_user);
/* 403 dedicated access protection registers */ /* 403 dedicated access protection registers */
......
...@@ -186,7 +186,7 @@ static int ppc6xx_tlb_getnum (CPUState *env, target_ulong eaddr, ...@@ -186,7 +186,7 @@ static int ppc6xx_tlb_getnum (CPUState *env, target_ulong eaddr,
void ppc6xx_tlb_invalidate_all (CPUState *env) void ppc6xx_tlb_invalidate_all (CPUState *env)
{ {
ppc_tlb_t *tlb; ppc6xx_tlb_t *tlb;
int nr, max; int nr, max;
#if defined (DEBUG_SOFTWARE_TLB) && 0 #if defined (DEBUG_SOFTWARE_TLB) && 0
...@@ -199,7 +199,7 @@ void ppc6xx_tlb_invalidate_all (CPUState *env) ...@@ -199,7 +199,7 @@ void ppc6xx_tlb_invalidate_all (CPUState *env)
if (env->id_tlbs == 1) if (env->id_tlbs == 1)
max *= 2; max *= 2;
for (nr = 0; nr < max; nr++) { for (nr = 0; nr < max; nr++) {
tlb = &env->tlb[nr]; tlb = &env->tlb[nr].tlb6;
#if !defined(FLUSH_ALL_TLBS) #if !defined(FLUSH_ALL_TLBS)
tlb_flush_page(env, tlb->EPN); tlb_flush_page(env, tlb->EPN);
#endif #endif
...@@ -214,14 +214,14 @@ static inline void __ppc6xx_tlb_invalidate_virt (CPUState *env, ...@@ -214,14 +214,14 @@ static inline void __ppc6xx_tlb_invalidate_virt (CPUState *env,
target_ulong eaddr, target_ulong eaddr,
int is_code, int match_epn) int is_code, int match_epn)
{ {
ppc_tlb_t *tlb; ppc6xx_tlb_t *tlb;
int way, nr; int way, nr;
#if !defined(FLUSH_ALL_TLBS) #if !defined(FLUSH_ALL_TLBS)
/* Invalidate ITLB + DTLB, all ways */ /* Invalidate ITLB + DTLB, all ways */
for (way = 0; way < env->nb_ways; way++) { for (way = 0; way < env->nb_ways; way++) {
nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code); 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 (pte_is_valid(tlb->pte0) && (match_epn == 0 || eaddr == tlb->EPN)) {
#if defined (DEBUG_SOFTWARE_TLB) #if defined (DEBUG_SOFTWARE_TLB)
if (loglevel != 0) { if (loglevel != 0) {
...@@ -248,11 +248,11 @@ void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr, ...@@ -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, void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
target_ulong pte0, target_ulong pte1) target_ulong pte0, target_ulong pte1)
{ {
ppc_tlb_t *tlb; ppc6xx_tlb_t *tlb;
int nr; int nr;
nr = ppc6xx_tlb_getnum(env, EPN, way, is_code); nr = ppc6xx_tlb_getnum(env, EPN, way, is_code);
tlb = &env->tlb[nr]; tlb = &env->tlb[nr].tlb6;
#if defined (DEBUG_SOFTWARE_TLB) #if defined (DEBUG_SOFTWARE_TLB)
if (loglevel != 0) { if (loglevel != 0) {
fprintf(logfile, "Set TLB %d/%d EPN " ADDRX " PTE0 " ADDRX 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,8 +264,6 @@ void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
tlb->pte0 = pte0; tlb->pte0 = pte0;
tlb->pte1 = pte1; tlb->pte1 = pte1;
tlb->EPN = EPN; tlb->EPN = EPN;
tlb->PID = 0;
tlb->size = 1;
/* Store last way for LRU mechanism */ /* Store last way for LRU mechanism */
env->last_way = way; env->last_way = way;
} }
...@@ -273,7 +271,7 @@ void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code, ...@@ -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, static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx,
target_ulong eaddr, int rw, int access_type) target_ulong eaddr, int rw, int access_type)
{ {
ppc_tlb_t *tlb; ppc6xx_tlb_t *tlb;
int nr, best, way; int nr, best, way;
int ret; int ret;
...@@ -282,7 +280,7 @@ static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx, ...@@ -282,7 +280,7 @@ static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx,
for (way = 0; way < env->nb_ways; way++) { for (way = 0; way < env->nb_ways; way++) {
nr = ppc6xx_tlb_getnum(env, eaddr, way, nr = ppc6xx_tlb_getnum(env, eaddr, way,
access_type == ACCESS_CODE ? 1 : 0); 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 */ /* This test "emulates" the PTE index match for hardware TLBs */
if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) { if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) {
#if defined (DEBUG_SOFTWARE_TLB) #if defined (DEBUG_SOFTWARE_TLB)
...@@ -339,7 +337,7 @@ static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx, ...@@ -339,7 +337,7 @@ static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx,
} }
#endif #endif
/* Update page flags */ /* 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; return ret;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册