Commit 0a032cbec69c268272a118f19e64c16e73d56cc0
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
Showing
6 changed files
with
87 additions
and
64 deletions
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[] = | ... | ... |