Add reset callbacks for PowerPC CPU.
Move cpu_ppc_init, cpu_ppc_close, cpu_ppc_reset and ppc_tlb_invalidate into helper.c as they are to be called from outside of the translated code. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2682 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									dd37a5e4d7
								
							
						
					
					
						commit
						0a032cbec6
					
				@ -317,6 +317,7 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* init CPUs */
 | 
					    /* init CPUs */
 | 
				
			||||||
    env = cpu_init();
 | 
					    env = cpu_init();
 | 
				
			||||||
 | 
					    qemu_register_reset(&cpu_ppc_reset, env);
 | 
				
			||||||
    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
 | 
					    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Default CPU is a generic 74x/75x */
 | 
					    /* Default CPU is a generic 74x/75x */
 | 
				
			||||||
 | 
				
			|||||||
@ -538,6 +538,7 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
 | 
				
			|||||||
    /* init CPUs */
 | 
					    /* init CPUs */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    env = cpu_init();
 | 
					    env = cpu_init();
 | 
				
			||||||
 | 
					    qemu_register_reset(&cpu_ppc_reset, env);
 | 
				
			||||||
    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
 | 
					    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Default CPU is a 604 */
 | 
					    /* Default CPU is a 604 */
 | 
				
			||||||
 | 
				
			|||||||
@ -860,6 +860,9 @@ void do_store_msr (CPUPPCState *env, target_ulong value);
 | 
				
			|||||||
void ppc_store_msr_32 (CPUPPCState *env, uint32_t value);
 | 
					void ppc_store_msr_32 (CPUPPCState *env, uint32_t value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void do_compute_hflags (CPUPPCState *env);
 | 
					void do_compute_hflags (CPUPPCState *env);
 | 
				
			||||||
 | 
					void cpu_ppc_reset (void *opaque);
 | 
				
			||||||
 | 
					CPUPPCState *cpu_ppc_init (void);
 | 
				
			||||||
 | 
					void cpu_ppc_close(CPUPPCState *env);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int ppc_find_by_name (const unsigned char *name, ppc_def_t **def);
 | 
					int ppc_find_by_name (const unsigned char *name, ppc_def_t **def);
 | 
				
			||||||
int ppc_find_by_pvr (uint32_t apvr, ppc_def_t **def);
 | 
					int ppc_find_by_pvr (uint32_t apvr, ppc_def_t **def);
 | 
				
			||||||
@ -883,6 +886,7 @@ target_ulong load_40x_pit (CPUPPCState *env);
 | 
				
			|||||||
void store_40x_pit (CPUPPCState *env, target_ulong val);
 | 
					void store_40x_pit (CPUPPCState *env, target_ulong 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);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -630,6 +630,25 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx,
 | 
				
			|||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					            tlb->prot &= ~PAGE_VALID;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    tlb_flush(env, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
 | 
					int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
 | 
				
			||||||
                                 target_ulong address, int rw, int access_type)
 | 
					                                 target_ulong address, int rw, int access_type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -1105,6 +1124,20 @@ void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
 | 
				
			|||||||
    env->DBAT[1][nr] = value;
 | 
					    env->DBAT[1][nr] = value;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*****************************************************************************/
 | 
				
			||||||
 | 
					/* TLB management */
 | 
				
			||||||
 | 
					void ppc_tlb_invalidate_all (CPUPPCState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
 | 
				
			||||||
 | 
					        ppc6xx_tlb_invalidate_all(env);
 | 
				
			||||||
 | 
					    } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
 | 
				
			||||||
 | 
					        ppc4xx_tlb_invalidate_all(env);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        tlb_flush(env, 1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*****************************************************************************/
 | 
					/*****************************************************************************/
 | 
				
			||||||
/* Special registers manipulation */
 | 
					/* Special registers manipulation */
 | 
				
			||||||
#if defined(TARGET_PPC64)
 | 
					#if defined(TARGET_PPC64)
 | 
				
			||||||
@ -2039,3 +2072,48 @@ void cpu_dump_EA (target_ulong EA)
 | 
				
			|||||||
    fprintf(f, "Memory access at address " TARGET_FMT_lx "\n", EA);
 | 
					    fprintf(f, "Memory access at address " TARGET_FMT_lx "\n", EA);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cpu_ppc_reset (void *opaque)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    CPUPPCState *env;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    env = opaque;
 | 
				
			||||||
 | 
					#if defined (DO_SINGLE_STEP) && 0
 | 
				
			||||||
 | 
					    /* Single step trace mode */
 | 
				
			||||||
 | 
					    msr_se = 1;
 | 
				
			||||||
 | 
					    msr_be = 1;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    msr_fp = 1; /* Allow floating point exceptions */
 | 
				
			||||||
 | 
					    msr_me = 1; /* Allow machine check exceptions  */
 | 
				
			||||||
 | 
					#if defined(TARGET_PPC64)
 | 
				
			||||||
 | 
					    msr_sf = 0; /* Boot in 32 bits mode */
 | 
				
			||||||
 | 
					    msr_cm = 0;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if defined(CONFIG_USER_ONLY)
 | 
				
			||||||
 | 
					    msr_pr = 1;
 | 
				
			||||||
 | 
					    tlb_flush(env, 1);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    env->nip = 0xFFFFFFFC;
 | 
				
			||||||
 | 
					    ppc_tlb_invalidate_all(env);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    do_compute_hflags(env);
 | 
				
			||||||
 | 
					    env->reserve = -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CPUPPCState *cpu_ppc_init (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    CPUPPCState *env;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    env = qemu_mallocz(sizeof(CPUPPCState));
 | 
				
			||||||
 | 
					    if (!env)
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    cpu_exec_init(env);
 | 
				
			||||||
 | 
					    cpu_ppc_reset(env);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return env;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cpu_ppc_close (CPUPPCState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* Should also remove all opcode tables... */
 | 
				
			||||||
 | 
					    free(env);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -2256,16 +2256,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
 | 
				
			|||||||
/* TLB invalidation helpers */
 | 
					/* TLB invalidation helpers */
 | 
				
			||||||
void do_tlbia (void)
 | 
					void do_tlbia (void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
 | 
					    ppc_tlb_invalidate_all(env);
 | 
				
			||||||
        ppc6xx_tlb_invalidate_all(env);
 | 
					 | 
				
			||||||
    } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
 | 
					 | 
				
			||||||
        /* XXX: TODO */
 | 
					 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
        ppcbooke_tlb_invalidate_all(env);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        tlb_flush(env, 1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void do_tlbie (void)
 | 
					void do_tlbie (void)
 | 
				
			||||||
@ -2473,25 +2464,6 @@ static int booke_page_size_to_tlb (target_ulong page_size)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helpers for 4xx TLB management */
 | 
					/* Helpers for 4xx TLB management */
 | 
				
			||||||
void do_4xx_tlbia (void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    ppcemb_tlb_t *tlb;
 | 
					 | 
				
			||||||
    int i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (i = 0; i < 64; i++) {
 | 
					 | 
				
			||||||
        tlb = &env->tlb[i].tlbe;
 | 
					 | 
				
			||||||
        if (tlb->prot & PAGE_VALID) {
 | 
					 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
            end = tlb->EPN + tlb->size;
 | 
					 | 
				
			||||||
            for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
 | 
					 | 
				
			||||||
                tlb_flush_page(env, page);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
            tlb->prot &= ~PAGE_VALID;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    tlb_flush(env, 1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void do_4xx_tlbre_lo (void)
 | 
					void do_4xx_tlbre_lo (void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ppcemb_tlb_t *tlb;
 | 
					    ppcemb_tlb_t *tlb;
 | 
				
			||||||
 | 
				
			|||||||
@ -2713,39 +2713,6 @@ int cpu_ppc_register (CPUPPCState *env, ppc_def_t *def)
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void do_compute_hflags (CPUPPCState *env);
 | 
					 | 
				
			||||||
CPUPPCState *cpu_ppc_init (void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    CPUPPCState *env;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    env = qemu_mallocz(sizeof(CPUPPCState));
 | 
					 | 
				
			||||||
    if (!env)
 | 
					 | 
				
			||||||
        return NULL;
 | 
					 | 
				
			||||||
    cpu_exec_init(env);
 | 
					 | 
				
			||||||
    tlb_flush(env, 1);
 | 
					 | 
				
			||||||
#if defined (DO_SINGLE_STEP) && 0
 | 
					 | 
				
			||||||
    /* Single step trace mode */
 | 
					 | 
				
			||||||
    msr_se = 1;
 | 
					 | 
				
			||||||
    msr_be = 1;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    msr_fp = 1; /* Allow floating point exceptions */
 | 
					 | 
				
			||||||
    msr_me = 1; /* Allow machine check exceptions  */
 | 
					 | 
				
			||||||
#if defined(CONFIG_USER_ONLY)
 | 
					 | 
				
			||||||
    msr_pr = 1;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    env->nip = 0xFFFFFFFC;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    do_compute_hflags(env);
 | 
					 | 
				
			||||||
    env->reserve = -1;
 | 
					 | 
				
			||||||
    return env;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void cpu_ppc_close(CPUPPCState *env)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /* Should also remove all opcode tables... */
 | 
					 | 
				
			||||||
    free(env);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*****************************************************************************/
 | 
					/*****************************************************************************/
 | 
				
			||||||
/* PowerPC CPU definitions */
 | 
					/* PowerPC CPU definitions */
 | 
				
			||||||
static ppc_def_t ppc_defs[] =
 | 
					static ppc_def_t ppc_defs[] =
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user