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,6 +317,7 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
317 317
318 /* init CPUs */ 318 /* init CPUs */
319 env = cpu_init(); 319 env = cpu_init();
  320 + qemu_register_reset(&cpu_ppc_reset, env);
320 register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); 321 register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
321 322
322 /* Default CPU is a generic 74x/75x */ 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,13 +531,14 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
531 531
532 sysctrl = qemu_mallocz(sizeof(sysctrl_t)); 532 sysctrl = qemu_mallocz(sizeof(sysctrl_t));
533 if (sysctrl == NULL) 533 if (sysctrl == NULL)
534 - return; 534 + return;
535 535
536 linux_boot = (kernel_filename != NULL); 536 linux_boot = (kernel_filename != NULL);
537 - 537 +
538 /* init CPUs */ 538 /* init CPUs */
539 539
540 env = cpu_init(); 540 env = cpu_init();
  541 + qemu_register_reset(&cpu_ppc_reset, env);
541 register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); 542 register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
542 543
543 /* Default CPU is a 604 */ 544 /* Default CPU is a 604 */
target-ppc/cpu.h
@@ -860,6 +860,9 @@ void do_store_msr (CPUPPCState *env, target_ulong value); @@ -860,6 +860,9 @@ void do_store_msr (CPUPPCState *env, target_ulong value);
860 void ppc_store_msr_32 (CPUPPCState *env, uint32_t value); 860 void ppc_store_msr_32 (CPUPPCState *env, uint32_t value);
861 861
862 void do_compute_hflags (CPUPPCState *env); 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 int ppc_find_by_name (const unsigned char *name, ppc_def_t **def); 867 int ppc_find_by_name (const unsigned char *name, ppc_def_t **def);
865 int ppc_find_by_pvr (uint32_t apvr, ppc_def_t **def); 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,6 +886,7 @@ target_ulong load_40x_pit (CPUPPCState *env);
883 void store_40x_pit (CPUPPCState *env, target_ulong val); 886 void store_40x_pit (CPUPPCState *env, target_ulong val);
884 void store_booke_tcr (CPUPPCState *env, target_ulong val); 887 void store_booke_tcr (CPUPPCState *env, target_ulong val);
885 void store_booke_tsr (CPUPPCState *env, target_ulong val); 888 void store_booke_tsr (CPUPPCState *env, target_ulong val);
  889 +void ppc_tlb_invalidate_all (CPUPPCState *env);
886 #endif 890 #endif
887 #endif 891 #endif
888 892
target-ppc/helper.c
@@ -630,6 +630,25 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx, @@ -630,6 +630,25 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx,
630 return ret; 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 int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx, 652 int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
634 target_ulong address, int rw, int access_type) 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,6 +1124,20 @@ void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
1105 env->DBAT[1][nr] = value; 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 /* Special registers manipulation */ 1142 /* Special registers manipulation */
1110 #if defined(TARGET_PPC64) 1143 #if defined(TARGET_PPC64)
@@ -2039,3 +2072,48 @@ void cpu_dump_EA (target_ulong EA) @@ -2039,3 +2072,48 @@ void cpu_dump_EA (target_ulong EA)
2039 fprintf(f, "Memory access at address " TARGET_FMT_lx "\n", EA); 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,16 +2256,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
2256 /* TLB invalidation helpers */ 2256 /* TLB invalidation helpers */
2257 void do_tlbia (void) 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 void do_tlbie (void) 2262 void do_tlbie (void)
@@ -2473,25 +2464,6 @@ static int booke_page_size_to_tlb (target_ulong page_size) @@ -2473,25 +2464,6 @@ static int booke_page_size_to_tlb (target_ulong page_size)
2473 } 2464 }
2474 2465
2475 /* Helpers for 4xx TLB management */ 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 void do_4xx_tlbre_lo (void) 2467 void do_4xx_tlbre_lo (void)
2496 { 2468 {
2497 ppcemb_tlb_t *tlb; 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,39 +2713,6 @@ int cpu_ppc_register (CPUPPCState *env, ppc_def_t *def)
2713 return 0; 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 /* PowerPC CPU definitions */ 2717 /* PowerPC CPU definitions */
2751 static ppc_def_t ppc_defs[] = 2718 static ppc_def_t ppc_defs[] =