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[] = | ... | ... |