Commit 0a032cbec69c268272a118f19e64c16e73d56cc0

Authored by j_mayer
1 parent dd37a5e4

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
hw/ppc_chrp.c
... ... @@ -317,6 +317,7 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
317 317  
318 318 /* init CPUs */
319 319 env = cpu_init();
  320 + qemu_register_reset(&cpu_ppc_reset, env);
320 321 register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
321 322  
322 323 /* Default CPU is a generic 74x/75x */
... ...
hw/ppc_prep.c
... ... @@ -531,13 +531,14 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
531 531  
532 532 sysctrl = qemu_mallocz(sizeof(sysctrl_t));
533 533 if (sysctrl == NULL)
534   - return;
  534 + return;
535 535  
536 536 linux_boot = (kernel_filename != NULL);
537   -
  537 +
538 538 /* init CPUs */
539 539  
540 540 env = cpu_init();
  541 + qemu_register_reset(&cpu_ppc_reset, env);
541 542 register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
542 543  
543 544 /* Default CPU is a 604 */
... ...
target-ppc/cpu.h
... ... @@ -860,6 +860,9 @@ void do_store_msr (CPUPPCState *env, target_ulong value);
860 860 void ppc_store_msr_32 (CPUPPCState *env, uint32_t value);
861 861  
862 862 void do_compute_hflags (CPUPPCState *env);
  863 +void cpu_ppc_reset (void *opaque);
  864 +CPUPPCState *cpu_ppc_init (void);
  865 +void cpu_ppc_close(CPUPPCState *env);
863 866  
864 867 int ppc_find_by_name (const unsigned char *name, ppc_def_t **def);
865 868 int ppc_find_by_pvr (uint32_t apvr, ppc_def_t **def);
... ... @@ -883,6 +886,7 @@ target_ulong load_40x_pit (CPUPPCState *env);
883 886 void store_40x_pit (CPUPPCState *env, target_ulong val);
884 887 void store_booke_tcr (CPUPPCState *env, target_ulong val);
885 888 void store_booke_tsr (CPUPPCState *env, target_ulong val);
  889 +void ppc_tlb_invalidate_all (CPUPPCState *env);
886 890 #endif
887 891 #endif
888 892  
... ...
target-ppc/helper.c
... ... @@ -630,6 +630,25 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx,
630 630 return ret;
631 631 }
632 632  
  633 +void ppc4xx_tlb_invalidate_all (CPUState *env)
  634 +{
  635 + ppcemb_tlb_t *tlb;
  636 + int i;
  637 +
  638 + for (i = 0; i < env->nb_tlb; i++) {
  639 + tlb = &env->tlb[i].tlbe;
  640 + if (tlb->prot & PAGE_VALID) {
  641 +#if 0 // XXX: TLB have variable sizes then we flush all Qemu TLB.
  642 + end = tlb->EPN + tlb->size;
  643 + for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
  644 + tlb_flush_page(env, page);
  645 +#endif
  646 + tlb->prot &= ~PAGE_VALID;
  647 + }
  648 + }
  649 + tlb_flush(env, 1);
  650 +}
  651 +
633 652 int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
634 653 target_ulong address, int rw, int access_type)
635 654 {
... ... @@ -1105,6 +1124,20 @@ void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
1105 1124 env->DBAT[1][nr] = value;
1106 1125 }
1107 1126  
  1127 +
  1128 +/*****************************************************************************/
  1129 +/* TLB management */
  1130 +void ppc_tlb_invalidate_all (CPUPPCState *env)
  1131 +{
  1132 + if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
  1133 + ppc6xx_tlb_invalidate_all(env);
  1134 + } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
  1135 + ppc4xx_tlb_invalidate_all(env);
  1136 + } else {
  1137 + tlb_flush(env, 1);
  1138 + }
  1139 +}
  1140 +
1108 1141 /*****************************************************************************/
1109 1142 /* Special registers manipulation */
1110 1143 #if defined(TARGET_PPC64)
... ... @@ -2039,3 +2072,48 @@ void cpu_dump_EA (target_ulong EA)
2039 2072 fprintf(f, "Memory access at address " TARGET_FMT_lx "\n", EA);
2040 2073 }
2041 2074  
  2075 +void cpu_ppc_reset (void *opaque)
  2076 +{
  2077 + CPUPPCState *env;
  2078 +
  2079 + env = opaque;
  2080 +#if defined (DO_SINGLE_STEP) && 0
  2081 + /* Single step trace mode */
  2082 + msr_se = 1;
  2083 + msr_be = 1;
  2084 +#endif
  2085 + msr_fp = 1; /* Allow floating point exceptions */
  2086 + msr_me = 1; /* Allow machine check exceptions */
  2087 +#if defined(TARGET_PPC64)
  2088 + msr_sf = 0; /* Boot in 32 bits mode */
  2089 + msr_cm = 0;
  2090 +#endif
  2091 +#if defined(CONFIG_USER_ONLY)
  2092 + msr_pr = 1;
  2093 + tlb_flush(env, 1);
  2094 +#else
  2095 + env->nip = 0xFFFFFFFC;
  2096 + ppc_tlb_invalidate_all(env);
  2097 +#endif
  2098 + do_compute_hflags(env);
  2099 + env->reserve = -1;
  2100 +}
  2101 +
  2102 +CPUPPCState *cpu_ppc_init (void)
  2103 +{
  2104 + CPUPPCState *env;
  2105 +
  2106 + env = qemu_mallocz(sizeof(CPUPPCState));
  2107 + if (!env)
  2108 + return NULL;
  2109 + cpu_exec_init(env);
  2110 + cpu_ppc_reset(env);
  2111 +
  2112 + return env;
  2113 +}
  2114 +
  2115 +void cpu_ppc_close (CPUPPCState *env)
  2116 +{
  2117 + /* Should also remove all opcode tables... */
  2118 + free(env);
  2119 +}
... ...
target-ppc/op_helper.c
... ... @@ -2256,16 +2256,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
2256 2256 /* TLB invalidation helpers */
2257 2257 void do_tlbia (void)
2258 2258 {
2259   - if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
2260   - ppc6xx_tlb_invalidate_all(env);
2261   - } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
2262   - /* XXX: TODO */
2263   -#if 0
2264   - ppcbooke_tlb_invalidate_all(env);
2265   -#endif
2266   - } else {
2267   - tlb_flush(env, 1);
2268   - }
  2259 + ppc_tlb_invalidate_all(env);
2269 2260 }
2270 2261  
2271 2262 void do_tlbie (void)
... ... @@ -2473,25 +2464,6 @@ static int booke_page_size_to_tlb (target_ulong page_size)
2473 2464 }
2474 2465  
2475 2466 /* Helpers for 4xx TLB management */
2476   -void do_4xx_tlbia (void)
2477   -{
2478   - ppcemb_tlb_t *tlb;
2479   - int i;
2480   -
2481   - for (i = 0; i < 64; i++) {
2482   - tlb = &env->tlb[i].tlbe;
2483   - if (tlb->prot & PAGE_VALID) {
2484   -#if 0
2485   - end = tlb->EPN + tlb->size;
2486   - for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
2487   - tlb_flush_page(env, page);
2488   -#endif
2489   - tlb->prot &= ~PAGE_VALID;
2490   - }
2491   - }
2492   - tlb_flush(env, 1);
2493   -}
2494   -
2495 2467 void do_4xx_tlbre_lo (void)
2496 2468 {
2497 2469 ppcemb_tlb_t *tlb;
... ...
target-ppc/translate_init.c
... ... @@ -2713,39 +2713,6 @@ int cpu_ppc_register (CPUPPCState *env, ppc_def_t *def)
2713 2713 return 0;
2714 2714 }
2715 2715  
2716   -void do_compute_hflags (CPUPPCState *env);
2717   -CPUPPCState *cpu_ppc_init (void)
2718   -{
2719   - CPUPPCState *env;
2720   -
2721   - env = qemu_mallocz(sizeof(CPUPPCState));
2722   - if (!env)
2723   - return NULL;
2724   - cpu_exec_init(env);
2725   - tlb_flush(env, 1);
2726   -#if defined (DO_SINGLE_STEP) && 0
2727   - /* Single step trace mode */
2728   - msr_se = 1;
2729   - msr_be = 1;
2730   -#endif
2731   - msr_fp = 1; /* Allow floating point exceptions */
2732   - msr_me = 1; /* Allow machine check exceptions */
2733   -#if defined(CONFIG_USER_ONLY)
2734   - msr_pr = 1;
2735   -#else
2736   - env->nip = 0xFFFFFFFC;
2737   -#endif
2738   - do_compute_hflags(env);
2739   - env->reserve = -1;
2740   - return env;
2741   -}
2742   -
2743   -void cpu_ppc_close(CPUPPCState *env)
2744   -{
2745   - /* Should also remove all opcode tables... */
2746   - free(env);
2747   -}
2748   -
2749 2716 /*****************************************************************************/
2750 2717 /* PowerPC CPU definitions */
2751 2718 static ppc_def_t ppc_defs[] =
... ...