Avoid op helpers that would just call helpers for TLB & SLB management:
call the helpers directly from the micro-ops. Avoid duplicated code for tlbsx. implementation. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3302 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									035feb8857
								
							
						
					
					
						commit
						daf4f96ece
					
				@ -656,6 +656,11 @@ void store_40x_sler (CPUPPCState *env, uint32_t val);
 | 
				
			|||||||
void store_booke_tcr (CPUPPCState *env, target_ulong val);
 | 
					void store_booke_tcr (CPUPPCState *env, target_ulong val);
 | 
				
			||||||
void store_booke_tsr (CPUPPCState *env, target_ulong val);
 | 
					void store_booke_tsr (CPUPPCState *env, target_ulong val);
 | 
				
			||||||
void ppc_tlb_invalidate_all (CPUPPCState *env);
 | 
					void ppc_tlb_invalidate_all (CPUPPCState *env);
 | 
				
			||||||
 | 
					void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr);
 | 
				
			||||||
 | 
					#if defined(TARGET_PPC64)
 | 
				
			||||||
 | 
					void ppc_slb_invalidate_all (CPUPPCState *env);
 | 
				
			||||||
 | 
					void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid);
 | 
					int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -100,14 +100,8 @@ void do_raise_exception (uint32_t exception);
 | 
				
			|||||||
int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong vaddr,
 | 
					int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong vaddr,
 | 
				
			||||||
                          int rw, int access_type, int check_BATs);
 | 
					                          int rw, int access_type, int check_BATs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ppc6xx_tlb_invalidate_all (CPUState *env);
 | 
					 | 
				
			||||||
void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
 | 
					 | 
				
			||||||
                                 int is_code);
 | 
					 | 
				
			||||||
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);
 | 
				
			||||||
void ppc4xx_tlb_invalidate_all (CPUState *env);
 | 
					 | 
				
			||||||
void ppc4xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
 | 
					 | 
				
			||||||
                                 uint32_t pid);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void env_to_regs (void)
 | 
					static inline void env_to_regs (void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -237,7 +237,7 @@ static int ppc6xx_tlb_getnum (CPUState *env, target_ulong eaddr,
 | 
				
			|||||||
    return nr;
 | 
					    return nr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ppc6xx_tlb_invalidate_all (CPUState *env)
 | 
					static void ppc6xx_tlb_invalidate_all (CPUState *env)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ppc6xx_tlb_t *tlb;
 | 
					    ppc6xx_tlb_t *tlb;
 | 
				
			||||||
    int nr, max;
 | 
					    int nr, max;
 | 
				
			||||||
@ -253,14 +253,9 @@ void ppc6xx_tlb_invalidate_all (CPUState *env)
 | 
				
			|||||||
        max *= 2;
 | 
					        max *= 2;
 | 
				
			||||||
    for (nr = 0; nr < max; nr++) {
 | 
					    for (nr = 0; nr < max; nr++) {
 | 
				
			||||||
        tlb = &env->tlb[nr].tlb6;
 | 
					        tlb = &env->tlb[nr].tlb6;
 | 
				
			||||||
#if !defined(FLUSH_ALL_TLBS)
 | 
					 | 
				
			||||||
        tlb_flush_page(env, tlb->EPN);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        pte_invalidate(&tlb->pte0);
 | 
					        pte_invalidate(&tlb->pte0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#if defined(FLUSH_ALL_TLBS)
 | 
					 | 
				
			||||||
    tlb_flush(env, 1);
 | 
					    tlb_flush(env, 1);
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void __ppc6xx_tlb_invalidate_virt (CPUState *env,
 | 
					static inline void __ppc6xx_tlb_invalidate_virt (CPUState *env,
 | 
				
			||||||
@ -292,8 +287,8 @@ static inline void __ppc6xx_tlb_invalidate_virt (CPUState *env,
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
 | 
					static void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
 | 
				
			||||||
                                 int is_code)
 | 
					                                        int is_code)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0);
 | 
					    __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -834,11 +829,13 @@ static int ppcemb_tlb_check (CPUState *env, ppcemb_tlb_t *tlb,
 | 
				
			|||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    mask = ~(tlb->size - 1);
 | 
					    mask = ~(tlb->size - 1);
 | 
				
			||||||
 | 
					#if defined (DEBUG_SOFTWARE_TLB)
 | 
				
			||||||
    if (loglevel != 0) {
 | 
					    if (loglevel != 0) {
 | 
				
			||||||
        fprintf(logfile, "%s: TLB %d address " ADDRX " PID %d <=> "
 | 
					        fprintf(logfile, "%s: TLB %d address " ADDRX " PID %d <=> "
 | 
				
			||||||
                ADDRX " " ADDRX " %d\n",
 | 
					                ADDRX " " ADDRX " %d\n",
 | 
				
			||||||
                __func__, i, address, pid, tlb->EPN, mask, (int)tlb->PID);
 | 
					                __func__, i, address, pid, tlb->EPN, mask, (int)tlb->PID);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    /* Check PID */
 | 
					    /* Check PID */
 | 
				
			||||||
    if (tlb->PID != 0 && tlb->PID != pid)
 | 
					    if (tlb->PID != 0 && tlb->PID != pid)
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
@ -876,9 +873,23 @@ int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid)
 | 
				
			|||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ppc4xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
 | 
					/* Helpers specific to PowerPC 40x implementations */
 | 
				
			||||||
                                 uint32_t pid)
 | 
					static void ppc4xx_tlb_invalidate_all (CPUState *env)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    ppcemb_tlb_t *tlb;
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < env->nb_tlb; i++) {
 | 
				
			||||||
 | 
					        tlb = &env->tlb[i].tlbe;
 | 
				
			||||||
 | 
					        tlb->prot &= ~PAGE_VALID;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    tlb_flush(env, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void ppc4xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
 | 
				
			||||||
 | 
					                                        uint32_t pid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if !defined(FLUSH_ALL_TLBS)
 | 
				
			||||||
    ppcemb_tlb_t *tlb;
 | 
					    ppcemb_tlb_t *tlb;
 | 
				
			||||||
    target_phys_addr_t raddr;
 | 
					    target_phys_addr_t raddr;
 | 
				
			||||||
    target_ulong page, end;
 | 
					    target_ulong page, end;
 | 
				
			||||||
@ -894,26 +905,9 @@ void ppc4xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
 | 
				
			|||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					#else
 | 
				
			||||||
 | 
					    ppc4xx_tlb_invalidate_all(env);
 | 
				
			||||||
/* Helpers specific to PowerPC 40x implementations */
 | 
					 | 
				
			||||||
void ppc4xx_tlb_invalidate_all (CPUState *env)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    ppcemb_tlb_t *tlb;
 | 
					 | 
				
			||||||
    int i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (i = 0; i < env->nb_tlb; i++) {
 | 
					 | 
				
			||||||
        tlb = &env->tlb[i].tlbe;
 | 
					 | 
				
			||||||
        if (tlb->prot & PAGE_VALID) {
 | 
					 | 
				
			||||||
#if 0 // XXX: TLB have variable sizes then we flush all Qemu TLB.
 | 
					 | 
				
			||||||
            end = tlb->EPN + tlb->size;
 | 
					 | 
				
			||||||
            for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
 | 
					 | 
				
			||||||
                tlb_flush_page(env, page);
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
            tlb->prot &= ~PAGE_VALID;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    tlb_flush(env, 1);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
 | 
					int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
 | 
				
			||||||
@ -932,10 +926,12 @@ int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
 | 
				
			|||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        zsel = (tlb->attr >> 4) & 0xF;
 | 
					        zsel = (tlb->attr >> 4) & 0xF;
 | 
				
			||||||
        zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3;
 | 
					        zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3;
 | 
				
			||||||
 | 
					#if defined (DEBUG_SOFTWARE_TLB)
 | 
				
			||||||
        if (loglevel != 0) {
 | 
					        if (loglevel != 0) {
 | 
				
			||||||
            fprintf(logfile, "%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
 | 
					            fprintf(logfile, "%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
 | 
				
			||||||
                    __func__, i, zsel, zpr, rw, tlb->attr);
 | 
					                    __func__, i, zsel, zpr, rw, tlb->attr);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
        if (access_type == ACCESS_CODE) {
 | 
					        if (access_type == ACCESS_CODE) {
 | 
				
			||||||
            /* Check execute enable bit */
 | 
					            /* Check execute enable bit */
 | 
				
			||||||
            switch (zpr) {
 | 
					            switch (zpr) {
 | 
				
			||||||
@ -1009,19 +1005,23 @@ int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        if (ret >= 0) {
 | 
					        if (ret >= 0) {
 | 
				
			||||||
            ctx->raddr = raddr;
 | 
					            ctx->raddr = raddr;
 | 
				
			||||||
 | 
					#if defined (DEBUG_SOFTWARE_TLB)
 | 
				
			||||||
            if (loglevel != 0) {
 | 
					            if (loglevel != 0) {
 | 
				
			||||||
                fprintf(logfile, "%s: access granted " ADDRX " => " REGX
 | 
					                fprintf(logfile, "%s: access granted " ADDRX " => " REGX
 | 
				
			||||||
                        " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
 | 
					                        " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
 | 
				
			||||||
                        ret);
 | 
					                        ret);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					#if defined (DEBUG_SOFTWARE_TLB)
 | 
				
			||||||
    if (loglevel != 0) {
 | 
					    if (loglevel != 0) {
 | 
				
			||||||
        fprintf(logfile, "%s: access refused " ADDRX " => " REGX
 | 
					        fprintf(logfile, "%s: access refused " ADDRX " => " REGX
 | 
				
			||||||
                " %d %d\n", __func__, address, raddr, ctx->prot,
 | 
					                " %d %d\n", __func__, address, raddr, ctx->prot,
 | 
				
			||||||
                ret);
 | 
					                ret);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1569,15 +1569,77 @@ void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
 | 
				
			|||||||
/* TLB management */
 | 
					/* TLB management */
 | 
				
			||||||
void ppc_tlb_invalidate_all (CPUPPCState *env)
 | 
					void ppc_tlb_invalidate_all (CPUPPCState *env)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) {
 | 
					    switch (env->mmu_model) {
 | 
				
			||||||
 | 
					    case POWERPC_MMU_SOFT_6xx:
 | 
				
			||||||
        ppc6xx_tlb_invalidate_all(env);
 | 
					        ppc6xx_tlb_invalidate_all(env);
 | 
				
			||||||
    } else if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_4xx)) {
 | 
					        break;
 | 
				
			||||||
 | 
					    case POWERPC_MMU_SOFT_4xx:
 | 
				
			||||||
 | 
					    case POWERPC_MMU_SOFT_4xx_Z:
 | 
				
			||||||
        ppc4xx_tlb_invalidate_all(env);
 | 
					        ppc4xx_tlb_invalidate_all(env);
 | 
				
			||||||
    } else {
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
        tlb_flush(env, 1);
 | 
					        tlb_flush(env, 1);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if !defined(FLUSH_ALL_TLBS)
 | 
				
			||||||
 | 
					    addr &= TARGET_PAGE_MASK;
 | 
				
			||||||
 | 
					    switch (env->mmu_model) {
 | 
				
			||||||
 | 
					    case POWERPC_MMU_SOFT_6xx:
 | 
				
			||||||
 | 
					        ppc6xx_tlb_invalidate_virt(env, addr, 0);
 | 
				
			||||||
 | 
					        if (env->id_tlbs == 1)
 | 
				
			||||||
 | 
					            ppc6xx_tlb_invalidate_virt(env, addr, 1);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case POWERPC_MMU_SOFT_4xx:
 | 
				
			||||||
 | 
					    case POWERPC_MMU_SOFT_4xx_Z:
 | 
				
			||||||
 | 
					        ppc4xx_tlb_invalidate_virt(env, addr, env->spr[SPR_40x_PID]);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        /* tlbie invalidate TLBs for all segments */
 | 
				
			||||||
 | 
					        addr &= ~((target_ulong)-1 << 28);
 | 
				
			||||||
 | 
					        /* XXX: this case should be optimized,
 | 
				
			||||||
 | 
					         * giving a mask to tlb_flush_page
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        tlb_flush_page(env, addr | (0x0 << 28));
 | 
				
			||||||
 | 
					        tlb_flush_page(env, addr | (0x1 << 28));
 | 
				
			||||||
 | 
					        tlb_flush_page(env, addr | (0x2 << 28));
 | 
				
			||||||
 | 
					        tlb_flush_page(env, addr | (0x3 << 28));
 | 
				
			||||||
 | 
					        tlb_flush_page(env, addr | (0x4 << 28));
 | 
				
			||||||
 | 
					        tlb_flush_page(env, addr | (0x5 << 28));
 | 
				
			||||||
 | 
					        tlb_flush_page(env, addr | (0x6 << 28));
 | 
				
			||||||
 | 
					        tlb_flush_page(env, addr | (0x7 << 28));
 | 
				
			||||||
 | 
					        tlb_flush_page(env, addr | (0x8 << 28));
 | 
				
			||||||
 | 
					        tlb_flush_page(env, addr | (0x9 << 28));
 | 
				
			||||||
 | 
					        tlb_flush_page(env, addr | (0xA << 28));
 | 
				
			||||||
 | 
					        tlb_flush_page(env, addr | (0xB << 28));
 | 
				
			||||||
 | 
					        tlb_flush_page(env, addr | (0xC << 28));
 | 
				
			||||||
 | 
					        tlb_flush_page(env, addr | (0xD << 28));
 | 
				
			||||||
 | 
					        tlb_flush_page(env, addr | (0xE << 28));
 | 
				
			||||||
 | 
					        tlb_flush_page(env, addr | (0xF << 28));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    ppc_tlb_invalidate_all(env);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(TARGET_PPC64)
 | 
				
			||||||
 | 
					void ppc_slb_invalidate_all (CPUPPCState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* XXX: TODO */
 | 
				
			||||||
 | 
					    tlb_flush(env, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* XXX: TODO */
 | 
				
			||||||
 | 
					    tlb_flush(env, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*****************************************************************************/
 | 
					/*****************************************************************************/
 | 
				
			||||||
/* Special registers manipulation */
 | 
					/* Special registers manipulation */
 | 
				
			||||||
#if defined(TARGET_PPC64)
 | 
					#if defined(TARGET_PPC64)
 | 
				
			||||||
 | 
				
			|||||||
@ -1985,21 +1985,21 @@ void OPPROTO op_td (void)
 | 
				
			|||||||
/* tlbia */
 | 
					/* tlbia */
 | 
				
			||||||
void OPPROTO op_tlbia (void)
 | 
					void OPPROTO op_tlbia (void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    do_tlbia();
 | 
					    ppc_tlb_invalidate_all(env);
 | 
				
			||||||
    RETURN();
 | 
					    RETURN();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* tlbie */
 | 
					/* tlbie */
 | 
				
			||||||
void OPPROTO op_tlbie (void)
 | 
					void OPPROTO op_tlbie (void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    do_tlbie();
 | 
					    ppc_tlb_invalidate_one(env, (uint32_t)T0);
 | 
				
			||||||
    RETURN();
 | 
					    RETURN();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(TARGET_PPC64)
 | 
					#if defined(TARGET_PPC64)
 | 
				
			||||||
void OPPROTO op_tlbie_64 (void)
 | 
					void OPPROTO op_tlbie_64 (void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    do_tlbie_64();
 | 
					    ppc_tlb_invalidate_one(env, T0);
 | 
				
			||||||
    RETURN();
 | 
					    RETURN();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -2007,13 +2007,19 @@ void OPPROTO op_tlbie_64 (void)
 | 
				
			|||||||
#if defined(TARGET_PPC64)
 | 
					#if defined(TARGET_PPC64)
 | 
				
			||||||
void OPPROTO op_slbia (void)
 | 
					void OPPROTO op_slbia (void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    do_slbia();
 | 
					    ppc_slb_invalidate_all(env);
 | 
				
			||||||
    RETURN();
 | 
					    RETURN();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_slbie (void)
 | 
					void OPPROTO op_slbie (void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    do_slbie();
 | 
					    ppc_slb_invalidate_one(env, (uint32_t)T0);
 | 
				
			||||||
 | 
					    RETURN();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OPPROTO op_slbie_64 (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ppc_slb_invalidate_one(env, T0);
 | 
				
			||||||
    RETURN();
 | 
					    RETURN();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -2487,13 +2493,18 @@ void OPPROTO op_440_tlbre (void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_440_tlbsx (void)
 | 
					void OPPROTO op_440_tlbsx (void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    do_440_tlbsx();
 | 
					    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
 | 
				
			||||||
    RETURN();
 | 
					    RETURN();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_440_tlbsx_ (void)
 | 
					void OPPROTO op_4xx_tlbsx_check (void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    do_440_tlbsx_();
 | 
					    int tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    tmp = xer_so;
 | 
				
			||||||
 | 
					    if (T0 != -1)
 | 
				
			||||||
 | 
					        tmp |= 0x02;
 | 
				
			||||||
 | 
					    env->crf[0] = tmp;
 | 
				
			||||||
    RETURN();
 | 
					    RETURN();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2517,13 +2528,7 @@ void OPPROTO op_4xx_tlbre_hi (void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void OPPROTO op_4xx_tlbsx (void)
 | 
					void OPPROTO op_4xx_tlbsx (void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    do_4xx_tlbsx();
 | 
					    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
 | 
				
			||||||
    RETURN();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_4xx_tlbsx_ (void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    do_4xx_tlbsx_();
 | 
					 | 
				
			||||||
    RETURN();
 | 
					    RETURN();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -36,7 +36,6 @@
 | 
				
			|||||||
//#define DEBUG_OP
 | 
					//#define DEBUG_OP
 | 
				
			||||||
//#define DEBUG_EXCEPTIONS
 | 
					//#define DEBUG_EXCEPTIONS
 | 
				
			||||||
//#define DEBUG_SOFTWARE_TLB
 | 
					//#define DEBUG_SOFTWARE_TLB
 | 
				
			||||||
//#define FLUSH_ALL_TLBS
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*****************************************************************************/
 | 
					/*****************************************************************************/
 | 
				
			||||||
/* Exceptions processing helpers */
 | 
					/* Exceptions processing helpers */
 | 
				
			||||||
@ -2336,118 +2335,6 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
 | 
				
			|||||||
    env = saved_env;
 | 
					    env = saved_env;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* TLB invalidation helpers */
 | 
					 | 
				
			||||||
void do_tlbia (void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    ppc_tlb_invalidate_all(env);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void do_tlbie (void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = (uint32_t)T0;
 | 
					 | 
				
			||||||
#if !defined(FLUSH_ALL_TLBS)
 | 
					 | 
				
			||||||
    /* XXX: Remove thoses tests */
 | 
					 | 
				
			||||||
    if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) {
 | 
					 | 
				
			||||||
        ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 0);
 | 
					 | 
				
			||||||
        if (env->id_tlbs == 1)
 | 
					 | 
				
			||||||
            ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 1);
 | 
					 | 
				
			||||||
    } else if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_4xx)) {
 | 
					 | 
				
			||||||
        ppc4xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK,
 | 
					 | 
				
			||||||
                                   env->spr[SPR_40x_PID]);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        /* tlbie invalidate TLBs for all segments */
 | 
					 | 
				
			||||||
        T0 &= TARGET_PAGE_MASK;
 | 
					 | 
				
			||||||
        T0 &= ~((target_ulong)-1 << 28);
 | 
					 | 
				
			||||||
        /* XXX: this case should be optimized,
 | 
					 | 
				
			||||||
         * giving a mask to tlb_flush_page
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x0 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x1 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x2 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x3 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x4 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x5 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x6 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x7 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x8 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x9 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0xA << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0xB << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0xC << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0xD << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0xE << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0xF << 28));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    do_tlbia();
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(TARGET_PPC64)
 | 
					 | 
				
			||||||
void do_tlbie_64 (void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = (uint64_t)T0;
 | 
					 | 
				
			||||||
#if !defined(FLUSH_ALL_TLBS)
 | 
					 | 
				
			||||||
    if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) {
 | 
					 | 
				
			||||||
        ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 0);
 | 
					 | 
				
			||||||
        if (env->id_tlbs == 1)
 | 
					 | 
				
			||||||
            ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 1);
 | 
					 | 
				
			||||||
    } else if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_4xx)) {
 | 
					 | 
				
			||||||
        /* XXX: TODO */
 | 
					 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
        ppcbooke_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK,
 | 
					 | 
				
			||||||
                                     env->spr[SPR_BOOKE_PID]);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        /* tlbie invalidate TLBs for all segments
 | 
					 | 
				
			||||||
         * As we have 2^36 segments, invalidate all qemu TLBs
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
        T0 &= TARGET_PAGE_MASK;
 | 
					 | 
				
			||||||
        T0 &= ~((target_ulong)-1 << 28);
 | 
					 | 
				
			||||||
        /* XXX: this case should be optimized,
 | 
					 | 
				
			||||||
         * giving a mask to tlb_flush_page
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x0 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x1 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x2 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x3 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x4 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x5 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x6 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x7 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x8 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0x9 << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0xA << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0xB << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0xC << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0xD << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0xE << 28));
 | 
					 | 
				
			||||||
        tlb_flush_page(env, T0 | (0xF << 28));
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
        tlb_flush(env, 1);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    do_tlbia();
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(TARGET_PPC64)
 | 
					 | 
				
			||||||
void do_slbia (void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /* XXX: TODO */
 | 
					 | 
				
			||||||
    tlb_flush(env, 1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void do_slbie (void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /* XXX: TODO */
 | 
					 | 
				
			||||||
    tlb_flush(env, 1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Software driven TLBs management */
 | 
					/* Software driven TLBs management */
 | 
				
			||||||
/* PowerPC 602/603 software TLB load instructions helpers */
 | 
					/* PowerPC 602/603 software TLB load instructions helpers */
 | 
				
			||||||
void do_load_6xx_tlb (int is_code)
 | 
					void do_load_6xx_tlb (int is_code)
 | 
				
			||||||
@ -2575,21 +2462,6 @@ void do_4xx_tlbre_hi (void)
 | 
				
			|||||||
        T0 |= 0x100;
 | 
					        T0 |= 0x100;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void do_4xx_tlbsx (void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void do_4xx_tlbsx_ (void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int tmp = xer_so;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
 | 
					 | 
				
			||||||
    if (T0 != -1)
 | 
					 | 
				
			||||||
        tmp |= 0x02;
 | 
					 | 
				
			||||||
    env->crf[0] = tmp;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void do_4xx_tlbwe_hi (void)
 | 
					void do_4xx_tlbwe_hi (void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ppcemb_tlb_t *tlb;
 | 
					    ppcemb_tlb_t *tlb;
 | 
				
			||||||
@ -2757,21 +2629,6 @@ void do_440_tlbwe (int word)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void do_440_tlbsx (void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void do_440_tlbsx_ (void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int tmp = xer_so;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
 | 
					 | 
				
			||||||
    if (T0 != -1)
 | 
					 | 
				
			||||||
        tmp |= 0x02;
 | 
					 | 
				
			||||||
    env->crf[0] = tmp;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void do_440_tlbre (int word)
 | 
					void do_440_tlbre (int word)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ppcemb_tlb_t *tlb;
 | 
					    ppcemb_tlb_t *tlb;
 | 
				
			||||||
 | 
				
			|||||||
@ -4991,10 +4991,9 @@ GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    gen_addr_reg_index(ctx);
 | 
					    gen_addr_reg_index(ctx);
 | 
				
			||||||
 | 
					    gen_op_4xx_tlbsx();
 | 
				
			||||||
    if (Rc(ctx->opcode))
 | 
					    if (Rc(ctx->opcode))
 | 
				
			||||||
        gen_op_4xx_tlbsx_();
 | 
					        gen_op_4xx_tlbsx_check();
 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        gen_op_4xx_tlbsx();
 | 
					 | 
				
			||||||
    gen_op_store_T0_gpr(rD(ctx->opcode));
 | 
					    gen_op_store_T0_gpr(rD(ctx->opcode));
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -5064,10 +5063,9 @@ GEN_HANDLER(tlbsx_440, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    gen_addr_reg_index(ctx);
 | 
					    gen_addr_reg_index(ctx);
 | 
				
			||||||
 | 
					    gen_op_440_tlbsx();
 | 
				
			||||||
    if (Rc(ctx->opcode))
 | 
					    if (Rc(ctx->opcode))
 | 
				
			||||||
        gen_op_440_tlbsx_();
 | 
					        gen_op_4xx_tlbsx_check();
 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        gen_op_440_tlbsx();
 | 
					 | 
				
			||||||
    gen_op_store_T0_gpr(rD(ctx->opcode));
 | 
					    gen_op_store_T0_gpr(rD(ctx->opcode));
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user