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 */
|
||||
env = cpu_init();
|
||||
qemu_register_reset(&cpu_ppc_reset, env);
|
||||
register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
|
||||
|
||||
/* 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 */
|
||||
|
||||
env = cpu_init();
|
||||
qemu_register_reset(&cpu_ppc_reset, env);
|
||||
register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
|
||||
|
||||
/* 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 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_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_booke_tcr (CPUPPCState *env, target_ulong val);
|
||||
void store_booke_tsr (CPUPPCState *env, target_ulong val);
|
||||
void ppc_tlb_invalidate_all (CPUPPCState *env);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -630,6 +630,25 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx,
|
||||
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,
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* 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 */
|
||||
#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);
|
||||
}
|
||||
|
||||
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 */
|
||||
void do_tlbia (void)
|
||||
{
|
||||
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)) {
|
||||
/* XXX: TODO */
|
||||
#if 0
|
||||
ppcbooke_tlb_invalidate_all(env);
|
||||
#endif
|
||||
} else {
|
||||
tlb_flush(env, 1);
|
||||
}
|
||||
ppc_tlb_invalidate_all(env);
|
||||
}
|
||||
|
||||
void do_tlbie (void)
|
||||
@ -2473,25 +2464,6 @@ static int booke_page_size_to_tlb (target_ulong page_size)
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
ppcemb_tlb_t *tlb;
|
||||
|
@ -2713,39 +2713,6 @@ int cpu_ppc_register (CPUPPCState *env, ppc_def_t *def)
|
||||
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 */
|
||||
static ppc_def_t ppc_defs[] =
|
||||
|
Loading…
Reference in New Issue
Block a user