/* 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 */
sysctrl = qemu_mallocz(sizeof(sysctrl_t));
if (sysctrl == NULL)
- return;
+ return;
linux_boot = (kernel_filename != NULL);
-
+
/* 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 */
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);
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
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)
{
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)
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);
+}
/* 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)
}
/* 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;
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[] =