mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-18 23:52:14 -06:00
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
This commit is contained in:
parent
05a8096f2d
commit
1d0a48fb92
2 changed files with 26 additions and 14 deletions
|
@ -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 {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 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 {
|
||||||
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,
|
||||||
|
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
#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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue