diff options
author | j_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-04-16 08:56:52 +0000 |
---|---|---|
committer | j_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-04-16 08:56:52 +0000 |
commit | 0a032cbec69c268272a118f19e64c16e73d56cc0 (patch) | |
tree | c2e2f0a67ac42a5729aaa50b73aebf5dca13f00a /target-ppc/helper.c | |
parent | dd37a5e4d7ebc4e698f4c69ad2a5ee922824703f (diff) |
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
Diffstat (limited to 'target-ppc/helper.c')
-rw-r--r-- | target-ppc/helper.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 161cc1b14b..5f46ae0fdc 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -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); +} |