aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-04-16 08:56:52 +0000
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-04-16 08:56:52 +0000
commit0a032cbec69c268272a118f19e64c16e73d56cc0 (patch)
treec2e2f0a67ac42a5729aaa50b73aebf5dca13f00a
parentdd37a5e4d7ebc4e698f4c69ad2a5ee922824703f (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
-rw-r--r--hw/ppc_chrp.c1
-rw-r--r--hw/ppc_prep.c5
-rw-r--r--target-ppc/cpu.h4
-rw-r--r--target-ppc/helper.c78
-rw-r--r--target-ppc/op_helper.c30
-rw-r--r--target-ppc/translate_init.c33
6 files changed, 87 insertions, 64 deletions
diff --git a/hw/ppc_chrp.c b/hw/ppc_chrp.c
index 8eef289828..456832824e 100644
--- a/hw/ppc_chrp.c
+++ b/hw/ppc_chrp.c
@@ -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 */
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 8fce9cc6cd..2f10338b13 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -531,13 +531,14 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
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 */
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 1e309f91d1..5cd1b6008c 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -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
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);
+}
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 140b7f5cb2..590b31e725 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -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;
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 018512328e..ab8d8694a8 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -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[] =