diff options
Diffstat (limited to 'target-ppc')
| -rw-r--r-- | target-ppc/arch_dump.c | 6 | ||||
| -rw-r--r-- | target-ppc/cpu-qom.h | 8 | ||||
| -rw-r--r-- | target-ppc/cpu.h | 17 | ||||
| -rw-r--r-- | target-ppc/excp_helper.c | 73 | ||||
| -rw-r--r-- | target-ppc/fpu_helper.c | 26 | ||||
| -rw-r--r-- | target-ppc/helper_regs.h | 2 | ||||
| -rw-r--r-- | target-ppc/int_helper.c | 4 | ||||
| -rw-r--r-- | target-ppc/kvm.c | 8 | ||||
| -rw-r--r-- | target-ppc/machine.c | 4 | ||||
| -rw-r--r-- | target-ppc/misc_helper.c | 4 | ||||
| -rw-r--r-- | target-ppc/mmu-hash32.c | 35 | ||||
| -rw-r--r-- | target-ppc/mmu-hash32.h | 14 | ||||
| -rw-r--r-- | target-ppc/mmu-hash64.c | 30 | ||||
| -rw-r--r-- | target-ppc/mmu-hash64.h | 8 | ||||
| -rw-r--r-- | target-ppc/mmu_helper.c | 208 | ||||
| -rw-r--r-- | target-ppc/translate.c | 4 | ||||
| -rw-r--r-- | target-ppc/translate_init.c | 66 | ||||
| -rw-r--r-- | target-ppc/user_only_helper.c | 8 |
18 files changed, 296 insertions, 229 deletions
diff --git a/target-ppc/arch_dump.c b/target-ppc/arch_dump.c index 17fd4c6fb1..9dccf1ae1f 100644 --- a/target-ppc/arch_dump.c +++ b/target-ppc/arch_dump.c @@ -164,7 +164,7 @@ static void ppc64_write_elf64_speregset(Note *note, PowerPCCPU *cpu) speregset->spe_fscr = cpu_to_be32(cpu->env.spe_fscr); } -struct NoteFuncDescStruct { +static const struct NoteFuncDescStruct { int contents_size; void (*note_contents_func)(Note *note, PowerPCCPU *cpu); } note_func[] = { @@ -196,7 +196,7 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) int name_size = 8; /* "CORE" or "QEMU" rounded */ size_t elf_note_size = 0; int note_head_size; - NoteFuncDesc *nf; + const NoteFuncDesc *nf; if (class != ELFCLASS64) { return -1; @@ -221,7 +221,7 @@ static int ppc64_write_all_elf64_notes(const char *note_name, Note note; int ret = -1; int note_size; - NoteFuncDesc *nf; + const NoteFuncDesc *nf; for (nf = note_func; nf->note_contents_func; nf++) { note.hdr.n_namesz = cpu_to_be32(sizeof(note.name)); diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h index b17c024543..47dc8e6fdf 100644 --- a/target-ppc/cpu-qom.h +++ b/target-ppc/cpu-qom.h @@ -38,6 +38,8 @@ #define POWERPC_CPU_GET_CLASS(obj) \ OBJECT_GET_CLASS(PowerPCCPUClass, (obj), TYPE_POWERPC_CPU) +typedef struct PowerPCCPU PowerPCCPU; + /** * PowerPCCPUClass: * @parent_realize: The parent class' realize handler. @@ -71,7 +73,7 @@ typedef struct PowerPCCPUClass { void (*init_proc)(CPUPPCState *env); int (*check_pow)(CPUPPCState *env); #if defined(CONFIG_SOFTMMU) - int (*handle_mmu_fault)(CPUPPCState *env, target_ulong eaddr, int rwx, + int (*handle_mmu_fault)(PowerPCCPU *cpu, target_ulong eaddr, int rwx, int mmu_idx); #endif } PowerPCCPUClass; @@ -83,14 +85,14 @@ typedef struct PowerPCCPUClass { * * A PowerPC CPU. */ -typedef struct PowerPCCPU { +struct PowerPCCPU { /*< private >*/ CPUState parent_obj; /*< public >*/ CPUPPCState env; int cpu_dt_id; -} PowerPCCPU; +}; static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env) { diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index afab267485..2719c08323 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -334,6 +334,7 @@ struct ppc_spr_t { void (*hea_write)(void *opaque, int spr_num, int gpr_num); #endif const char *name; + target_ulong default_value; #ifdef CONFIG_KVM /* We (ab)use the fact that all the SPRs will have ids for the * ONE_REG interface will have KVM_REG_PPC to use 0 as meaning, @@ -1111,8 +1112,8 @@ int cpu_ppc_signal_handler (int host_signum, void *pinfo, void *puc); void ppc_hw_interrupt (CPUPPCState *env); #if defined(CONFIG_USER_ONLY) -int cpu_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw, - int mmu_idx); +int ppc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, + int mmu_idx); #endif #if !defined(CONFIG_USER_ONLY) @@ -1900,6 +1901,8 @@ enum { PPC2_LSQ_ISA207 = 0x0000000000002000ULL, /* ISA 2.07 Altivec */ PPC2_ALTIVEC_207 = 0x0000000000004000ULL, + /* PowerISA 2.07 Book3s specification */ + PPC2_ISA207S = 0x0000000000008000ULL, #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \ PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \ @@ -2100,7 +2103,7 @@ static inline int booke206_tlbm_to_tlbn(CPUPPCState *env, ppcmas_tlb_t *tlbm) } } - cpu_abort(env, "Unknown TLBe: %d\n", id); + cpu_abort(CPU(ppc_env_get_cpu(env)), "Unknown TLBe: %d\n", id); return 0; } @@ -2171,14 +2174,6 @@ static inline bool msr_is_64bit(CPUPPCState *env, target_ulong msr) extern void (*cpu_ppc_hypercall)(PowerPCCPU *); -static inline bool cpu_has_work(CPUState *cpu) -{ - PowerPCCPU *ppc_cpu = POWERPC_CPU(cpu); - CPUPPCState *env = &ppc_cpu->env; - - return msr_ee && (cpu->interrupt_request & CPU_INTERRUPT_HARD); -} - #include "exec/exec-all.h" void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env); diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c index d541929743..19bc6b66ba 100644 --- a/target-ppc/excp_helper.c +++ b/target-ppc/excp_helper.c @@ -43,13 +43,15 @@ void ppc_cpu_do_interrupt(CPUState *cs) PowerPCCPU *cpu = POWERPC_CPU(cs); CPUPPCState *env = &cpu->env; - env->exception_index = POWERPC_EXCP_NONE; + cs->exception_index = POWERPC_EXCP_NONE; env->error_code = 0; } void ppc_hw_interrupt(CPUPPCState *env) { - env->exception_index = POWERPC_EXCP_NONE; + CPUState *cs = CPU(ppc_env_get_cpu(env)); + + cs->exception_index = POWERPC_EXCP_NONE; env->error_code = 0; } #else /* defined(CONFIG_USER_ONLY) */ @@ -68,8 +70,8 @@ static inline void dump_syscall(CPUPPCState *env) */ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) { + CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; - CPUState *cs; target_ulong msr, new_msr, vector; int srr0, srr1, asrr0, asrr1; int lpes0, lpes1, lev; @@ -135,7 +137,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) fprintf(stderr, "Machine check while not allowed. " "Entering checkstop state\n"); } - cs = CPU(cpu); cs->halted = 1; cs->interrupt_request |= CPU_INTERRUPT_EXITTB; } @@ -204,7 +205,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) case POWERPC_EXCP_FP: if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { LOG_EXCP("Ignore floating point exception\n"); - env->exception_index = POWERPC_EXCP_NONE; + cs->exception_index = POWERPC_EXCP_NONE; env->error_code = 0; return; } @@ -241,7 +242,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) break; default: /* Should never occur */ - cpu_abort(env, "Invalid program exception %d. Aborting\n", + cpu_abort(cs, "Invalid program exception %d. Aborting\n", env->error_code); break; } @@ -301,26 +302,26 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) break; } /* XXX: TODO */ - cpu_abort(env, "Debug exception is not implemented yet !\n"); + cpu_abort(cs, "Debug exception is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable */ env->spr[SPR_BOOKE_ESR] = ESR_SPV; goto store_current; case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */ /* XXX: TODO */ - cpu_abort(env, "Embedded floating point data exception " + cpu_abort(cs, "Embedded floating point data exception " "is not implemented yet !\n"); env->spr[SPR_BOOKE_ESR] = ESR_SPV; goto store_next; case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */ /* XXX: TODO */ - cpu_abort(env, "Embedded floating point round exception " + cpu_abort(cs, "Embedded floating point round exception " "is not implemented yet !\n"); env->spr[SPR_BOOKE_ESR] = ESR_SPV; goto store_next; case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */ /* XXX: TODO */ - cpu_abort(env, + cpu_abort(cs, "Performance counter exception is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */ @@ -402,15 +403,15 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) goto store_next; case POWERPC_EXCP_IO: /* IO error exception */ /* XXX: TODO */ - cpu_abort(env, "601 IO error exception is not implemented yet !\n"); + cpu_abort(cs, "601 IO error exception is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_RUNM: /* Run mode exception */ /* XXX: TODO */ - cpu_abort(env, "601 run mode exception is not implemented yet !\n"); + cpu_abort(cs, "601 run mode exception is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_EMUL: /* Emulation trap exception */ /* XXX: TODO */ - cpu_abort(env, "602 emulation trap exception " + cpu_abort(cs, "602 emulation trap exception " "is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */ @@ -428,7 +429,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) case POWERPC_EXCP_74xx: goto tlb_miss_74xx; default: - cpu_abort(env, "Invalid instruction TLB miss exception\n"); + cpu_abort(cs, "Invalid instruction TLB miss exception\n"); break; } break; @@ -447,7 +448,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) case POWERPC_EXCP_74xx: goto tlb_miss_74xx; default: - cpu_abort(env, "Invalid data load TLB miss exception\n"); + cpu_abort(cs, "Invalid data load TLB miss exception\n"); break; } break; @@ -533,30 +534,30 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) msr |= env->error_code; /* key bit */ break; default: - cpu_abort(env, "Invalid data store TLB miss exception\n"); + cpu_abort(cs, "Invalid data store TLB miss exception\n"); break; } goto store_next; case POWERPC_EXCP_FPA: /* Floating-point assist exception */ /* XXX: TODO */ - cpu_abort(env, "Floating point assist exception " + cpu_abort(cs, "Floating point assist exception " "is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_DABR: /* Data address breakpoint */ /* XXX: TODO */ - cpu_abort(env, "DABR exception is not implemented yet !\n"); + cpu_abort(cs, "DABR exception is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ /* XXX: TODO */ - cpu_abort(env, "IABR exception is not implemented yet !\n"); + cpu_abort(cs, "IABR exception is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_SMI: /* System management interrupt */ /* XXX: TODO */ - cpu_abort(env, "SMI exception is not implemented yet !\n"); + cpu_abort(cs, "SMI exception is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_THERM: /* Thermal interrupt */ /* XXX: TODO */ - cpu_abort(env, "Thermal management exception " + cpu_abort(cs, "Thermal management exception " "is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ @@ -564,36 +565,36 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) new_msr |= (target_ulong)MSR_HVB; } /* XXX: TODO */ - cpu_abort(env, + cpu_abort(cs, "Performance counter exception is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_VPUA: /* Vector assist exception */ /* XXX: TODO */ - cpu_abort(env, "VPU assist exception is not implemented yet !\n"); + cpu_abort(cs, "VPU assist exception is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_SOFTP: /* Soft patch exception */ /* XXX: TODO */ - cpu_abort(env, + cpu_abort(cs, "970 soft-patch exception is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_MAINT: /* Maintenance exception */ /* XXX: TODO */ - cpu_abort(env, + cpu_abort(cs, "970 maintenance exception is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */ /* XXX: TODO */ - cpu_abort(env, "Maskable external exception " + cpu_abort(cs, "Maskable external exception " "is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */ /* XXX: TODO */ - cpu_abort(env, "Non maskable external exception " + cpu_abort(cs, "Non maskable external exception " "is not implemented yet !\n"); goto store_next; default: excp_invalid: - cpu_abort(env, "Invalid PowerPC exception %d. Aborting\n", excp); + cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); break; store_current: /* save current instruction location */ @@ -615,7 +616,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) } /* If we disactivated any translation, flush TLBs */ if (msr & ((1 << MSR_IR) | (1 << MSR_DR))) { - tlb_flush(env, 1); + tlb_flush(cs, 1); } #ifdef TARGET_PPC64 @@ -635,7 +636,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) /* Jump to handler */ vector = env->excp_vectors[excp]; if (vector == (target_ulong)-1ULL) { - cpu_abort(env, "Raised an exception without defined vector %d\n", + cpu_abort(cs, "Raised an exception without defined vector %d\n", excp); } vector |= env->excp_prefix; @@ -662,7 +663,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) hreg_compute_hflags(env); env->nip = vector; /* Reset exception state */ - env->exception_index = POWERPC_EXCP_NONE; + cs->exception_index = POWERPC_EXCP_NONE; env->error_code = 0; if ((env->mmu_model == POWERPC_MMU_BOOKE) || @@ -670,7 +671,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) /* XXX: The BookE changes address space when switching modes, we should probably implement that as different MMU indexes, but for the moment we do it the slow way and flush all. */ - tlb_flush(env, 1); + tlb_flush(cs, 1); } } @@ -679,7 +680,7 @@ void ppc_cpu_do_interrupt(CPUState *cs) PowerPCCPU *cpu = POWERPC_CPU(cs); CPUPPCState *env = &cpu->env; - powerpc_excp(cpu, env->excp_model, env->exception_index); + powerpc_excp(cpu, env->excp_model, cs->exception_index); } void ppc_hw_interrupt(CPUPPCState *env) @@ -815,12 +816,14 @@ static void cpu_dump_rfi(target_ulong RA, target_ulong msr) void helper_raise_exception_err(CPUPPCState *env, uint32_t exception, uint32_t error_code) { + CPUState *cs = CPU(ppc_env_get_cpu(env)); + #if 0 printf("Raise exception %3x code : %d\n", exception, error_code); #endif - env->exception_index = exception; + cs->exception_index = exception; env->error_code = error_code; - cpu_loop_exit(env); + cpu_loop_exit(cs); } void helper_raise_exception(CPUPPCState *env, uint32_t exception) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index e7f329566d..fd91239d37 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -119,6 +119,7 @@ uint32_t helper_compute_fprf(CPUPPCState *env, uint64_t arg, uint32_t set_fprf) static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op, int set_fpcc) { + CPUState *cs = CPU(ppc_env_get_cpu(env)); uint64_t ret = 0; int ve; @@ -155,7 +156,7 @@ static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op, } /* We must update the target FPR before raising the exception */ if (ve != 0) { - env->exception_index = POWERPC_EXCP_PROGRAM; + cs->exception_index = POWERPC_EXCP_PROGRAM; env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_VXVC; /* Update the floating-point enabled exception summary */ env->fpscr |= 1 << FPSCR_FEX; @@ -224,6 +225,8 @@ static inline void float_zero_divide_excp(CPUPPCState *env) static inline void float_overflow_excp(CPUPPCState *env) { + CPUState *cs = CPU(ppc_env_get_cpu(env)); + env->fpscr |= 1 << FPSCR_OX; /* Update the floating-point exception summary */ env->fpscr |= 1 << FPSCR_FX; @@ -232,7 +235,7 @@ static inline void float_overflow_excp(CPUPPCState *env) /* Update the floating-point enabled exception summary */ env->fpscr |= 1 << FPSCR_FEX; /* We must update the target FPR before raising the exception */ - env->exception_index = POWERPC_EXCP_PROGRAM; + cs->exception_index = POWERPC_EXCP_PROGRAM; env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_OX; } else { env->fpscr |= 1 << FPSCR_XX; @@ -242,6 +245,8 @@ static inline void float_overflow_excp(CPUPPCState *env) static inline void float_underflow_excp(CPUPPCState *env) { + CPUState *cs = CPU(ppc_env_get_cpu(env)); + env->fpscr |= 1 << FPSCR_UX; /* Update the floating-point exception summary */ env->fpscr |= 1 << FPSCR_FX; @@ -250,13 +255,15 @@ static inline void float_underflow_excp(CPUPPCState *env) /* Update the floating-point enabled exception summary */ env->fpscr |= 1 << FPSCR_FEX; /* We must update the target FPR before raising the exception */ - env->exception_index = POWERPC_EXCP_PROGRAM; + cs->exception_index = POWERPC_EXCP_PROGRAM; env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_UX; } } static inline void float_inexact_excp(CPUPPCState *env) { + CPUState *cs = CPU(ppc_env_get_cpu(env)); + env->fpscr |= 1 << FPSCR_XX; /* Update the floating-point exception summary */ env->fpscr |= 1 << FPSCR_FX; @@ -264,7 +271,7 @@ static inline void float_inexact_excp(CPUPPCState *env) /* Update the floating-point enabled exception summary */ env->fpscr |= 1 << FPSCR_FEX; /* We must update the target FPR before raising the exception */ - env->exception_index = POWERPC_EXCP_PROGRAM; + cs->exception_index = POWERPC_EXCP_PROGRAM; env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_XX; } } @@ -316,6 +323,7 @@ void helper_fpscr_clrbit(CPUPPCState *env, uint32_t bit) void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit) { + CPUState *cs = CPU(ppc_env_get_cpu(env)); int prev; prev = (env->fpscr >> bit) & 1; @@ -439,7 +447,7 @@ void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit) /* Update the floating-point enabled exception summary */ env->fpscr |= 1 << FPSCR_FEX; /* We have to update Rc1 before raising the exception */ - env->exception_index = POWERPC_EXCP_PROGRAM; + cs->exception_index = POWERPC_EXCP_PROGRAM; break; } } @@ -447,6 +455,7 @@ void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit) void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask) { + CPUState *cs = CPU(ppc_env_get_cpu(env)); target_ulong prev, new; int i; @@ -468,7 +477,7 @@ void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask) } if ((fpscr_ex & fpscr_eex) != 0) { env->fpscr |= 1 << FPSCR_FEX; - env->exception_index = POWERPC_EXCP_PROGRAM; + cs->exception_index = POWERPC_EXCP_PROGRAM; /* XXX: we should compute it properly */ env->error_code = POWERPC_EXCP_FP; } else { @@ -484,6 +493,7 @@ void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask) void helper_float_check_status(CPUPPCState *env) { + CPUState *cs = CPU(ppc_env_get_cpu(env)); int status = get_float_exception_flags(&env->fp_status); if (status & float_flag_divbyzero) { @@ -496,11 +506,11 @@ void helper_float_check_status(CPUPPCState *env) float_inexact_excp(env); } - if (env->exception_index == POWERPC_EXCP_PROGRAM && + if (cs->exception_index == POWERPC_EXCP_PROGRAM && (env->error_code & POWERPC_EXCP_FP)) { /* Differred floating-point exception after target FPR update */ if (msr_fe0 != 0 || msr_fe1 != 0) { - helper_raise_exception_err(env, env->exception_index, + helper_raise_exception_err(env, cs->exception_index, env->error_code); } } diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h index c02e8da4e4..f7ec9c2b81 100644 --- a/target-ppc/helper_regs.h +++ b/target-ppc/helper_regs.h @@ -83,7 +83,7 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value, if (((value >> MSR_IR) & 1) != msr_ir || ((value >> MSR_DR) & 1) != msr_dr) { /* Flush all tlb when changing translation mode */ - tlb_flush(env, 1); + tlb_flush(cs, 1); excp = POWERPC_EXCP_NONE; cs->interrupt_request |= CPU_INTERRUPT_EXITTB; } diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c index 63dde94b04..18b54f060a 100644 --- a/target-ppc/int_helper.c +++ b/target-ppc/int_helper.c @@ -1075,7 +1075,7 @@ void helper_vbpermq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) #undef VBPERMQ_INDEX #undef VBPERMQ_DW -uint64_t VGBBD_MASKS[256] = { +static const uint64_t VGBBD_MASKS[256] = { 0x0000000000000000ull, /* 00 */ 0x0000000000000080ull, /* 01 */ 0x0000000000008000ull, /* 02 */ @@ -2216,7 +2216,7 @@ static int bcd_cmp_mag(ppc_avr_t *a, ppc_avr_t *b) uint8_t dig_a = bcd_get_digit(a, i, &invalid); uint8_t dig_b = bcd_get_digit(b, i, &invalid); if (unlikely(invalid)) { - return 0; /* doesnt matter */ + return 0; /* doesn't matter */ } else if (dig_a > dig_b) { return 1; } else if (dig_a < dig_b) { diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 32e7a8c0a7..9974b10ccb 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -1178,7 +1178,7 @@ static int kvmppc_handle_halt(PowerPCCPU *cpu) if (!(cs->interrupt_request & CPU_INTERRUPT_HARD) && (msr_ee)) { cs->halted = 1; - env->exception_index = EXCP_HLT; + cs->exception_index = EXCP_HLT; } return 0; @@ -1504,7 +1504,6 @@ int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len) void kvmppc_set_papr(PowerPCCPU *cpu) { - CPUPPCState *env = &cpu->env; CPUState *cs = CPU(cpu); struct kvm_enable_cap cap = {}; int ret; @@ -1513,7 +1512,7 @@ void kvmppc_set_papr(PowerPCCPU *cpu) ret = kvm_vcpu_ioctl(cs, KVM_ENABLE_CAP, &cap); if (ret) { - cpu_abort(env, "This KVM version does not support PAPR\n"); + cpu_abort(cs, "This KVM version does not support PAPR\n"); } /* Update the capability flag so we sync the right information @@ -1523,7 +1522,6 @@ void kvmppc_set_papr(PowerPCCPU *cpu) void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy) { - CPUPPCState *env = &cpu->env; CPUState *cs = CPU(cpu); struct kvm_enable_cap cap = {}; int ret; @@ -1533,7 +1531,7 @@ void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy) ret = kvm_vcpu_ioctl(cs, KVM_ENABLE_CAP, &cap); if (ret && mpic_proxy) { - cpu_abort(env, "This KVM version does not support EPR\n"); + cpu_abort(cs, "This KVM version does not support EPR\n"); } } diff --git a/target-ppc/machine.c b/target-ppc/machine.c index 2d46ceccca..063b379d90 100644 --- a/target-ppc/machine.c +++ b/target-ppc/machine.c @@ -114,7 +114,7 @@ static void put_avr(QEMUFile *f, void *pv, size_t size) qemu_put_be64(f, v->u64[1]); } -const VMStateInfo vmstate_info_avr = { +static const VMStateInfo vmstate_info_avr = { .name = "avr", .get = get_avr, .put = put_avr, @@ -288,7 +288,7 @@ static void put_slbe(QEMUFile *f, void *pv, size_t size) qemu_put_be64(f, v->vsid); } -const VMStateInfo vmstate_info_slbe = { +static const VMStateInfo vmstate_info_slbe = { .name = "slbe", .get = get_slbe, .put = put_slbe, diff --git a/target-ppc/misc_helper.c b/target-ppc/misc_helper.c index dc2ebfc452..2eb2fa6e20 100644 --- a/target-ppc/misc_helper.c +++ b/target-ppc/misc_helper.c @@ -62,10 +62,12 @@ void helper_store_hid0_601(CPUPPCState *env, target_ulong val) void helper_store_403_pbr(CPUPPCState *env, uint32_t num, target_ulong value) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); + if (likely(env->pb[num] != value)) { env->pb[num] = value; /* Should be optimized */ - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } } diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c index 6a77dc4f97..1cc19162b7 100644 --- a/target-ppc/mmu-hash32.c +++ b/target-ppc/mmu-hash32.c @@ -222,6 +222,7 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr, target_ulong eaddr, int rwx, hwaddr *raddr, int *prot) { + CPUState *cs = CPU(ppc_env_get_cpu(env)); int key = !!(msr_pr ? (sr & SR32_KP) : (sr & SR32_KS)); LOG_MMU("direct store...\n"); @@ -238,7 +239,7 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr, if (rwx == 2) { /* No code fetch is allowed in direct-store areas */ - env->exception_index = POWERPC_EXCP_ISI; + cs->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x10000000; return 1; } @@ -249,7 +250,7 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr, break; case ACCESS_FLOAT: /* Floating point load/store */ - env->exception_index = POWERPC_EXCP_ALIGN; + cs->exception_index = POWERPC_EXCP_ALIGN; env->error_code = POWERPC_EXCP_ALIGN_FP; env->spr[SPR_DAR] = eaddr; return 1; @@ -272,7 +273,7 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr, return 0; case ACCESS_EXT: /* eciwx or ecowx */ - env->exception_index = POWERPC_EXCP_DSI; + cs->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; env->spr[SPR_DAR] = eaddr; if (rwx == 1) { @@ -290,7 +291,7 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr, *raddr = eaddr; return 0; } else { - env->exception_index = POWERPC_EXCP_DSI; + cs->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; env->spr[SPR_DAR] = eaddr; if (rwx == 1) { @@ -380,9 +381,11 @@ static hwaddr ppc_hash32_pte_raddr(target_ulong sr, ppc_hash_pte32_t pte, return (rpn & ~mask) | (eaddr & mask); } -int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx, +int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, target_ulong eaddr, int rwx, int mmu_idx) { + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; target_ulong sr; hwaddr pte_offset; ppc_hash_pte32_t pte; @@ -397,7 +400,7 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx, if (((rwx == 2) && (msr_ir == 0)) || ((rwx != 2) && (msr_dr == 0))) { /* Translation is off */ raddr = eaddr; - tlb_set_page(env, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK, + tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK, PAGE_READ | PAGE_WRITE | PAGE_EXEC, mmu_idx, TARGET_PAGE_SIZE); return 0; @@ -409,10 +412,10 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx, if (raddr != -1) { if (need_prot[rwx] & ~prot) { if (rwx == 2) { - env->exception_index = POWERPC_EXCP_ISI; + cs->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x08000000; } else { - env->exception_index = POWERPC_EXCP_DSI; + cs->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; env->spr[SPR_DAR] = eaddr; if (rwx == 1) { @@ -424,7 +427,7 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx, return 1; } - tlb_set_page(env, eaddr & TARGET_PAGE_MASK, + tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK, prot, mmu_idx, TARGET_PAGE_SIZE); return 0; @@ -438,7 +441,7 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx, if (sr & SR32_T) { if (ppc_hash32_direct_store(env, sr, eaddr, rwx, &raddr, &prot) == 0) { - tlb_set_page(env, eaddr & TARGET_PAGE_MASK, + tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK, prot, mmu_idx, TARGET_PAGE_SIZE); return 0; @@ -449,7 +452,7 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx, /* 5. Check for segment level no-execute violation */ if ((rwx == 2) && (sr & SR32_NX)) { - env->exception_index = POWERPC_EXCP_ISI; + cs->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x10000000; return 1; } @@ -458,10 +461,10 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx, pte_offset = ppc_hash32_htab_lookup(env, sr, eaddr, &pte); if (pte_offset == -1) { if (rwx == 2) { - env->exception_index = POWERPC_EXCP_ISI; + cs->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x40000000; } else { - env->exception_index = POWERPC_EXCP_DSI; + cs->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; env->spr[SPR_DAR] = eaddr; if (rwx == 1) { @@ -483,10 +486,10 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx, /* Access right violation */ LOG_MMU("PTE access rejected\n"); if (rwx == 2) { - env->exception_index = POWERPC_EXCP_ISI; + cs->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x08000000; } else { - env->exception_index = POWERPC_EXCP_DSI; + cs->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; env->spr[SPR_DAR] = eaddr; if (rwx == 1) { @@ -519,7 +522,7 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx, raddr = ppc_hash32_pte_raddr(sr, pte, eaddr); - tlb_set_page(env, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK, + tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK, prot, mmu_idx, TARGET_PAGE_SIZE); return 0; diff --git a/target-ppc/mmu-hash32.h b/target-ppc/mmu-hash32.h index 4671141a32..d515d4ff73 100644 --- a/target-ppc/mmu-hash32.h +++ b/target-ppc/mmu-hash32.h @@ -5,7 +5,7 @@ hwaddr get_pteg_offset32(CPUPPCState *env, hwaddr hash); hwaddr ppc_hash32_get_phys_page_debug(CPUPPCState *env, target_ulong addr); -int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw, +int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, target_ulong address, int rw, int mmu_idx); /* @@ -68,7 +68,8 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw, static inline target_ulong ppc_hash32_load_hpte0(CPUPPCState *env, hwaddr pte_offset) { - CPUState *cs = ENV_GET_CPU(env); + CPUState *cs = CPU(ppc_env_get_cpu(env)); + assert(!env->external_htab); /* Not supported on 32-bit for now */ return ldl_phys(cs->as, env->htab_base + pte_offset); } @@ -76,7 +77,8 @@ static inline target_ulong ppc_hash32_load_hpte0(CPUPPCState *env, static inline target_ulong ppc_hash32_load_hpte1(CPUPPCState *env, hwaddr pte_offset) { - CPUState *cs = ENV_GET_CPU(env); + CPUState *cs = CPU(ppc_env_get_cpu(env)); + assert(!env->external_htab); /* Not supported on 32-bit for now */ return ldl_phys(cs->as, env->htab_base + pte_offset + HASH_PTE_SIZE_32/2); } @@ -84,7 +86,8 @@ static inline target_ulong ppc_hash32_load_hpte1(CPUPPCState *env, static inline void ppc_hash32_store_hpte0(CPUPPCState *env, hwaddr pte_offset, target_ulong pte0) { - CPUState *cs = ENV_GET_CPU(env); + CPUState *cs = CPU(ppc_env_get_cpu(env)); + assert(!env->external_htab); /* Not supported on 32-bit for now */ stl_phys(cs->as, env->htab_base + pte_offset, pte0); } @@ -92,7 +95,8 @@ static inline void ppc_hash32_store_hpte0(CPUPPCState *env, static inline void ppc_hash32_store_hpte1(CPUPPCState *env, hwaddr pte_offset, target_ulong pte1) { - CPUState *cs = ENV_GET_CPU(env); + CPUState *cs = CPU(ppc_env_get_cpu(env)); + assert(!env->external_htab); /* Not supported on 32-bit for now */ stl_phys(cs->as, env->htab_base + pte_offset + HASH_PTE_SIZE_32/2, pte1); } diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c index f2af4fbaa7..1fefe5881e 100644 --- a/target-ppc/mmu-hash64.c +++ b/target-ppc/mmu-hash64.c @@ -99,6 +99,7 @@ void dump_slb(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env) void helper_slbia(CPUPPCState *env) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); int n, do_invalidate; do_invalidate = 0; @@ -116,12 +117,13 @@ void helper_slbia(CPUPPCState *env) } } if (do_invalidate) { - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } } void helper_slbie(CPUPPCState *env, target_ulong addr) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); ppc_slb_t *slb; slb = slb_lookup(env, addr); @@ -136,7 +138,7 @@ void helper_slbie(CPUPPCState *env, target_ulong addr) * and we still don't have a tlb_flush_mask(env, n, mask) * in QEMU, we just invalidate all TLBs */ - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } } @@ -454,9 +456,11 @@ static hwaddr ppc_hash64_pte_raddr(ppc_slb_t *slb, ppc_hash_pte64_t pte, return (rpn & ~mask) | (eaddr & mask); } -int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, +int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, target_ulong eaddr, int rwx, int mmu_idx) { + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; ppc_slb_t *slb; hwaddr pte_offset; ppc_hash_pte64_t pte; @@ -472,7 +476,7 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, /* Translation is off */ /* In real mode the top 4 effective address bits are ignored */ raddr = eaddr & 0x0FFFFFFFFFFFFFFFULL; - tlb_set_page(env, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK, + tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK, PAGE_READ | PAGE_WRITE | PAGE_EXEC, mmu_idx, TARGET_PAGE_SIZE); return 0; @@ -483,10 +487,10 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, if (!slb) { if (rwx == 2) { - env->exception_index = POWERPC_EXCP_ISEG; + cs->exception_index = POWERPC_EXCP_ISEG; env->error_code = 0; } else { - env->exception_index = POWERPC_EXCP_DSEG; + cs->exception_index = POWERPC_EXCP_DSEG; env->error_code = 0; env->spr[SPR_DAR] = eaddr; } @@ -495,7 +499,7 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, /* 3. Check for segment level no-execute violation */ if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) { - env->exception_index = POWERPC_EXCP_ISI; + cs->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x10000000; return 1; } @@ -504,10 +508,10 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, pte_offset = ppc_hash64_htab_lookup(env, slb, eaddr, &pte); if (pte_offset == -1) { if (rwx == 2) { - env->exception_index = POWERPC_EXCP_ISI; + cs->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x40000000; } else { - env->exception_index = POWERPC_EXCP_DSI; + cs->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; env->spr[SPR_DAR] = eaddr; if (rwx == 1) { @@ -530,12 +534,12 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, /* Access right violation */ LOG_MMU("PTE access rejected\n"); if (rwx == 2) { - env->exception_index = POWERPC_EXCP_ISI; + cs->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x08000000; } else { target_ulong dsisr = 0; - env->exception_index = POWERPC_EXCP_DSI; + cs->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; env->spr[SPR_DAR] = eaddr; if (need_prot[rwx] & ~pp_prot) { @@ -574,7 +578,7 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, raddr = ppc_hash64_pte_raddr(slb, pte, eaddr); - tlb_set_page(env, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK, + tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK, prot, mmu_idx, TARGET_PAGE_SIZE); return 0; @@ -608,7 +612,7 @@ void ppc_hash64_store_hpte(CPUPPCState *env, target_ulong pte_index, target_ulong pte0, target_ulong pte1) { - CPUState *cs = ENV_GET_CPU(env); + CPUState *cs = CPU(ppc_env_get_cpu(env)); if (kvmppc_kern_htab) { return kvmppc_hash64_write_pte(env, pte_index, pte0, pte1); diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h index 1746b3e2d3..49e385db90 100644 --- a/target-ppc/mmu-hash64.h +++ b/target-ppc/mmu-hash64.h @@ -7,7 +7,7 @@ void dump_slb(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env); int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs); hwaddr ppc_hash64_get_phys_page_debug(CPUPPCState *env, target_ulong addr); -int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw, +int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, target_ulong address, int rw, int mmu_idx); void ppc_hash64_store_hpte(CPUPPCState *env, target_ulong index, target_ulong pte0, target_ulong pte1); @@ -85,8 +85,9 @@ void ppc_hash64_stop_access(uint64_t token); static inline target_ulong ppc_hash64_load_hpte0(CPUPPCState *env, uint64_t token, int index) { - CPUState *cs = ENV_GET_CPU(env); + CPUState *cs = CPU(ppc_env_get_cpu(env)); uint64_t addr; + addr = token + (index * HASH_PTE_SIZE_64); if (env->external_htab) { return ldq_p((const void *)(uintptr_t)addr); @@ -98,8 +99,9 @@ static inline target_ulong ppc_hash64_load_hpte0(CPUPPCState *env, static inline target_ulong ppc_hash64_load_hpte1(CPUPPCState *env, uint64_t token, int index) { - CPUState *cs = ENV_GET_CPU(env); + CPUState *cs = CPU(ppc_env_get_cpu(env)); uint64_t addr; + addr = token + (index * HASH_PTE_SIZE_64) + HASH_PTE_SIZE_64/2; if (env->external_htab) { return ldq_p((const void *)(uintptr_t)addr); diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c index 8e2f8e736a..1771863dff 100644 --- a/target-ppc/mmu_helper.c +++ b/target-ppc/mmu_helper.c @@ -231,6 +231,7 @@ static inline int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr, static inline void ppc6xx_tlb_invalidate_all(CPUPPCState *env) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); ppc6xx_tlb_t *tlb; int nr, max; @@ -244,7 +245,7 @@ static inline void ppc6xx_tlb_invalidate_all(CPUPPCState *env) tlb = &env->tlb.tlb6[nr]; pte_invalidate(&tlb->pte0); } - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } static inline void ppc6xx_tlb_invalidate_virt2(CPUPPCState *env, @@ -252,6 +253,7 @@ static inline void ppc6xx_tlb_invalidate_virt2(CPUPPCState *env, int is_code, int match_epn) { #if !defined(FLUSH_ALL_TLBS) + CPUState *cs = CPU(ppc_env_get_cpu(env)); ppc6xx_tlb_t *tlb; int way, nr; @@ -263,7 +265,7 @@ static inline void ppc6xx_tlb_invalidate_virt2(CPUPPCState *env, LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx "\n", nr, env->nb_tlb, eaddr); pte_invalidate(&tlb->pte0); - tlb_flush_page(env, tlb->EPN); + tlb_flush_page(cs, tlb->EPN); } } #else @@ -643,6 +645,7 @@ static int ppcemb_tlb_search(CPUPPCState *env, target_ulong address, /* Helpers specific to PowerPC 40x implementations */ static inline void ppc4xx_tlb_invalidate_all(CPUPPCState *env) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); ppcemb_tlb_t *tlb; int i; @@ -650,13 +653,14 @@ static inline void ppc4xx_tlb_invalidate_all(CPUPPCState *env) tlb = &env->tlb.tlbe[i]; tlb->prot &= ~PAGE_VALID; } - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } static inline void ppc4xx_tlb_invalidate_virt(CPUPPCState *env, target_ulong eaddr, uint32_t pid) { #if !defined(FLUSH_ALL_TLBS) + CPUState *cs = CPU(ppc_env_get_cpu(env)); ppcemb_tlb_t *tlb; hwaddr raddr; target_ulong page, end; @@ -667,7 +671,7 @@ static inline void ppc4xx_tlb_invalidate_virt(CPUPPCState *env, if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) { end = tlb->EPN + tlb->size; for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) { - tlb_flush_page(env, page); + tlb_flush_page(cs, page); } tlb->prot &= ~PAGE_VALID; break; @@ -746,9 +750,11 @@ static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, void store_40x_sler(CPUPPCState *env, uint32_t val) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); + /* XXX: TO BE FIXED */ if (val != 0x00000000) { - cpu_abort(env, "Little-endian regions are not supported by now\n"); + cpu_abort(CPU(cpu), "Little-endian regions are not supported by now\n"); } env->spr[SPR_405_SLER] = val; } @@ -858,6 +864,7 @@ static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, static void booke206_flush_tlb(CPUPPCState *env, int flags, const int check_iprot) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); int tlb_size; int i, j; ppcmas_tlb_t *tlb = env->tlb.tlbm; @@ -874,7 +881,7 @@ static void booke206_flush_tlb(CPUPPCState *env, int flags, tlb += booke206_tlb_size(env, i); } - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } static hwaddr booke206_tlb_to_page_size(CPUPPCState *env, @@ -1344,6 +1351,7 @@ static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx, static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong eaddr, int rw, int access_type) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); int ret = -1; bool real_mode = (access_type == ACCESS_CODE && msr_ir == 0) || (access_type != ACCESS_CODE && msr_dr == 0); @@ -1388,17 +1396,17 @@ static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, break; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ - cpu_abort(env, "MPC8xx MMU model is not implemented\n"); + cpu_abort(CPU(cpu), "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_REAL: if (real_mode) { ret = check_physical(env, ctx, eaddr, rw); } else { - cpu_abort(env, "PowerPC in real mode do not do any translation\n"); + cpu_abort(CPU(cpu), "PowerPC in real mode do not do any translation\n"); } return -1; default: - cpu_abort(env, "Unknown or invalid MMU model\n"); + cpu_abort(CPU(cpu), "Unknown or invalid MMU model\n"); return -1; } #if 0 @@ -1491,6 +1499,7 @@ static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address, static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw, int mmu_idx) { + CPUState *cs = CPU(ppc_env_get_cpu(env)); mmu_ctx_t ctx; int access_type; int ret = 0; @@ -1505,29 +1514,29 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, } ret = get_physical_address(env, &ctx, address, rw, access_type); if (ret == 0) { - tlb_set_page(env, address & TARGET_PAGE_MASK, + tlb_set_page(cs, address & TARGET_PAGE_MASK, ctx.raddr & TARGET_PAGE_MASK, ctx.prot, mmu_idx, TARGET_PAGE_SIZE); ret = 0; } else if (ret < 0) { - LOG_MMU_STATE(CPU(ppc_env_get_cpu(env))); + LOG_MMU_STATE(cs); if (access_type == ACCESS_CODE) { switch (ret) { case -1: /* No matches in page tables or TLB */ switch (env->mmu_model) { case POWERPC_MMU_SOFT_6xx: - env->exception_index = POWERPC_EXCP_IFTLB; + cs->exception_index = POWERPC_EXCP_IFTLB; env->error_code = 1 << 18; env->spr[SPR_IMISS] = address; env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem; goto tlb_miss; case POWERPC_MMU_SOFT_74xx: - env->exception_index = POWERPC_EXCP_IFTLB; + cs->exception_index = POWERPC_EXCP_IFTLB; goto tlb_miss_74xx; case POWERPC_MMU_SOFT_4xx: case POWERPC_MMU_SOFT_4xx_Z: - env->exception_index = POWERPC_EXCP_ITLB; + cs->exception_index = POWERPC_EXCP_ITLB; env->error_code = 0; env->spr[SPR_40x_DEAR] = address; env->spr[SPR_40x_ESR] = 0x00000000; @@ -1536,26 +1545,26 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, booke206_update_mas_tlb_miss(env, address, rw); /* fall through */ case POWERPC_MMU_BOOKE: - env->exception_index = POWERPC_EXCP_ITLB; + cs->exception_index = POWERPC_EXCP_ITLB; env->error_code = 0; env->spr[SPR_BOOKE_DEAR] = address; return -1; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ - cpu_abort(env, "MPC8xx MMU model is not implemented\n"); + cpu_abort(cs, "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_REAL: - cpu_abort(env, "PowerPC in real mode should never raise " + cpu_abort(cs, "PowerPC in real mode should never raise " "any MMU exceptions\n"); return -1; default: - cpu_abort(env, "Unknown or invalid MMU model\n"); + cpu_abort(cs, "Unknown or invalid MMU model\n"); return -1; } break; case -2: /* Access rights violation */ - env->exception_index = POWERPC_EXCP_ISI; + cs->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x08000000; break; case -3: @@ -1564,13 +1573,13 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, (env->mmu_model == POWERPC_MMU_BOOKE206)) { env->spr[SPR_BOOKE_ESR] = 0x00000000; } - env->exception_index = POWERPC_EXCP_ISI; + cs->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x10000000; break; case -4: /* Direct store exception */ /* No code fetch is allowed in direct-store areas */ - env->exception_index = POWERPC_EXCP_ISI; + cs->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x10000000; break; } @@ -1581,10 +1590,10 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, switch (env->mmu_model) { case POWERPC_MMU_SOFT_6xx: if (rw == 1) { - env->exception_index = POWERPC_EXCP_DSTLB; + cs->exception_index = POWERPC_EXCP_DSTLB; env->error_code = 1 << 16; } else { - env->exception_index = POWERPC_EXCP_DLTLB; + cs->exception_index = POWERPC_EXCP_DLTLB; env->error_code = 0; } env->spr[SPR_DMISS] = address; @@ -1598,9 +1607,9 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, break; case POWERPC_MMU_SOFT_74xx: if (rw == 1) { - env->exception_index = POWERPC_EXCP_DSTLB; + cs->exception_index = POWERPC_EXCP_DSTLB; } else { - env->exception_index = POWERPC_EXCP_DLTLB; + cs->exception_index = POWERPC_EXCP_DLTLB; } tlb_miss_74xx: /* Implement LRU algorithm */ @@ -1611,7 +1620,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, break; case POWERPC_MMU_SOFT_4xx: case POWERPC_MMU_SOFT_4xx_Z: - env->exception_index = POWERPC_EXCP_DTLB; + cs->exception_index = POWERPC_EXCP_DTLB; env->error_code = 0; env->spr[SPR_40x_DEAR] = address; if (rw) { @@ -1622,29 +1631,29 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, break; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ - cpu_abort(env, "MPC8xx MMU model is not implemented\n"); + cpu_abort(cs, "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_BOOKE206: booke206_update_mas_tlb_miss(env, address, rw); /* fall through */ case POWERPC_MMU_BOOKE: - env->exception_index = POWERPC_EXCP_DTLB; + cs->exception_index = POWERPC_EXCP_DTLB; env->error_code = 0; env->spr[SPR_BOOKE_DEAR] = address; env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0; return -1; case POWERPC_MMU_REAL: - cpu_abort(env, "PowerPC in real mode should never raise " + cpu_abort(cs, "PowerPC in real mode should never raise " "any MMU exceptions\n"); return -1; default: - cpu_abort(env, "Unknown or invalid MMU model\n"); + cpu_abort(cs, "Unknown or invalid MMU model\n"); return -1; } break; case -2: /* Access rights violation */ - env->exception_index = POWERPC_EXCP_DSI; + cs->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; if (env->mmu_model == POWERPC_MMU_SOFT_4xx || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) { @@ -1670,13 +1679,13 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, switch (access_type) { case ACCESS_FLOAT: /* Floating point load/store */ - env->exception_index = POWERPC_EXCP_ALIGN; + cs->exception_index = POWERPC_EXCP_ALIGN; env->error_code = POWERPC_EXCP_ALIGN_FP; env->spr[SPR_DAR] = address; break; case ACCESS_RES: /* lwarx, ldarx or stwcx. */ - env->exception_index = POWERPC_EXCP_DSI; + cs->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; env->spr[SPR_DAR] = address; if (rw == 1) { @@ -1687,7 +1696,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, break; case ACCESS_EXT: /* eciwx or ecowx */ - env->exception_index = POWERPC_EXCP_DSI; + cs->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; env->spr[SPR_DAR] = address; if (rw == 1) { @@ -1698,7 +1707,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, break; default: printf("DSI: invalid exception (%d)\n", ret); - env->exception_index = POWERPC_EXCP_PROGRAM; + cs->exception_index = POWERPC_EXCP_PROGRAM; env->error_code = POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL; env->spr[SPR_DAR] = address; @@ -1709,7 +1718,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, } #if 0 printf("%s: set exception to %d %02x\n", __func__, - env->exception, env->error_code); + cs->exception, env->error_code); #endif ret = 1; } @@ -1723,6 +1732,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu, target_ulong mask) { + CPUState *cs = CPU(ppc_env_get_cpu(env)); target_ulong base, end, page; base = BATu & ~0x0001FFFF; @@ -1730,7 +1740,7 @@ static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu, LOG_BATS("Flush BAT from " TARGET_FMT_lx " to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n", base, end, mask); for (page = base; page != end; page += TARGET_PAGE_SIZE) { - tlb_flush_page(env, page); + tlb_flush_page(cs, page); } LOG_BATS("Flush done\n"); } @@ -1892,6 +1902,8 @@ void helper_store_601_batl(CPUPPCState *env, uint32_t nr, target_ulong value) /* TLB management */ void ppc_tlb_invalidate_all(CPUPPCState *env) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); + switch (env->mmu_model) { case POWERPC_MMU_SOFT_6xx: case POWERPC_MMU_SOFT_74xx: @@ -1902,14 +1914,14 @@ void ppc_tlb_invalidate_all(CPUPPCState *env) ppc4xx_tlb_invalidate_all(env); break; case POWERPC_MMU_REAL: - cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n"); + cpu_abort(CPU(cpu), "No TLB for PowerPC 4xx in real mode\n"); break; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ - cpu_abort(env, "MPC8xx MMU model is not implemented\n"); + cpu_abort(CPU(cpu), "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_BOOKE: - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); break; case POWERPC_MMU_BOOKE206: booke206_flush_tlb(env, -1, 0); @@ -1922,11 +1934,11 @@ void ppc_tlb_invalidate_all(CPUPPCState *env) case POWERPC_MMU_2_06a: case POWERPC_MMU_2_06d: #endif /* defined(TARGET_PPC64) */ - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); break; default: /* XXX: TODO */ - cpu_abort(env, "Unknown MMU model\n"); + cpu_abort(CPU(cpu), "Unknown MMU model\n"); break; } } @@ -1934,6 +1946,9 @@ void ppc_tlb_invalidate_all(CPUPPCState *env) void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr) { #if !defined(FLUSH_ALL_TLBS) + PowerPCCPU *cpu = ppc_env_get_cpu(env); + CPUState *cs; + addr &= TARGET_PAGE_MASK; switch (env->mmu_model) { case POWERPC_MMU_SOFT_6xx: @@ -1948,43 +1963,44 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr) ppc4xx_tlb_invalidate_virt(env, addr, env->spr[SPR_40x_PID]); break; case POWERPC_MMU_REAL: - cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n"); + cpu_abort(CPU(cpu), "No TLB for PowerPC 4xx in real mode\n"); break; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ - cpu_abort(env, "MPC8xx MMU model is not implemented\n"); + cpu_abort(CPU(cpu), "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_BOOKE: /* XXX: TODO */ - cpu_abort(env, "BookE MMU model is not implemented\n"); + cpu_abort(CPU(cpu), "BookE MMU model is not implemented\n"); break; case POWERPC_MMU_BOOKE206: /* XXX: TODO */ - cpu_abort(env, "BookE 2.06 MMU model is not implemented\n"); + cpu_abort(CPU(cpu), "BookE 2.06 MMU model is not implemented\n"); break; case POWERPC_MMU_32B: case POWERPC_MMU_601: /* tlbie invalidate TLBs for all segments */ addr &= ~((target_ulong)-1ULL << 28); + cs = CPU(cpu); /* XXX: this case should be optimized, * giving a mask to tlb_flush_page */ - tlb_flush_page(env, addr | (0x0 << 28)); - tlb_flush_page(env, addr | (0x1 << 28)); - tlb_flush_page(env, addr | (0x2 << 28)); - tlb_flush_page(env, addr | (0x3 << 28)); - tlb_flush_page(env, addr | (0x4 << 28)); - tlb_flush_page(env, addr | (0x5 << 28)); - tlb_flush_page(env, addr | (0x6 << 28)); - tlb_flush_page(env, addr | (0x7 << 28)); - tlb_flush_page(env, addr | (0x8 << 28)); - tlb_flush_page(env, addr | (0x9 << 28)); - tlb_flush_page(env, addr | (0xA << 28)); - tlb_flush_page(env, addr | (0xB << 28)); - tlb_flush_page(env, addr | (0xC << 28)); - tlb_flush_page(env, addr | (0xD << 28)); - tlb_flush_page(env, addr | (0xE << 28)); - tlb_flush_page(env, addr | (0xF << 28)); + tlb_flush_page(cs, addr | (0x0 << 28)); + tlb_flush_page(cs, addr | (0x1 << 28)); + tlb_flush_page(cs, addr | (0x2 << 28)); + tlb_flush_page(cs, addr | (0x3 << 28)); + tlb_flush_page(cs, addr | (0x4 << 28)); + tlb_flush_page(cs, addr | (0x5 << 28)); + tlb_flush_page(cs, addr | (0x6 << 28)); + tlb_flush_page(cs, addr | (0x7 << 28)); + tlb_flush_page(cs, addr | (0x8 << 28)); + tlb_flush_page(cs, addr | (0x9 << 28)); + tlb_flush_page(cs, addr | (0xA << 28)); + tlb_flush_page(cs, addr | (0xB << 28)); + tlb_flush_page(cs, addr | (0xC << 28)); + tlb_flush_page(cs, addr | (0xD << 28)); + tlb_flush_page(cs, addr | (0xE << 28)); + tlb_flush_page(cs, addr | (0xF << 28)); break; #if defined(TARGET_PPC64) case POWERPC_MMU_64B: @@ -1996,12 +2012,12 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr) * and we still don't have a tlb_flush_mask(env, n, mask) in QEMU, * we just invalidate all TLBs */ - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); break; #endif /* defined(TARGET_PPC64) */ default: /* XXX: TODO */ - cpu_abort(env, "Unknown MMU model\n"); + cpu_abort(CPU(cpu), "Unknown MMU model\n"); break; } #else @@ -2013,6 +2029,8 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr) /* Special registers manipulation */ void ppc_store_sdr1(CPUPPCState *env, target_ulong value) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); + LOG_MMU("%s: " TARGET_FMT_lx "\n", __func__, value); assert(!env->external_htab); if (env->spr[SPR_SDR1] != value) { @@ -2035,7 +2053,7 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value) env->htab_mask = ((value & SDR_32_HTABMASK) << 16) | 0xFFFF; env->htab_base = value & SDR_32_HTABORG; } - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } } @@ -2053,6 +2071,8 @@ target_ulong helper_load_sr(CPUPPCState *env, target_ulong sr_num) void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); + LOG_MMU("%s: reg=%d " TARGET_FMT_lx " " TARGET_FMT_lx "\n", __func__, (int)srnum, value, env->sr[srnum]); #if defined(TARGET_PPC64) @@ -2085,11 +2105,11 @@ void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value) page = (16 << 20) * srnum; end = page + (16 << 20); for (; page != end; page += TARGET_PAGE_SIZE) { - tlb_flush_page(env, page); + tlb_flush_page(CPU(cpu), page); } } #else - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); #endif } } @@ -2316,6 +2336,8 @@ target_ulong helper_4xx_tlbre_lo(CPUPPCState *env, target_ulong entry) void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry, target_ulong val) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); + CPUState *cs = CPU(cpu); ppcemb_tlb_t *tlb; target_ulong page, end; @@ -2329,7 +2351,7 @@ void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry, LOG_SWTLB("%s: invalidate old TLB %d start " TARGET_FMT_lx " end " TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end); for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) { - tlb_flush_page(env, page); + tlb_flush_page(cs, page); } } tlb->size = booke_tlb_to_page_size((val >> PPC4XX_TLBHI_SIZE_SHIFT) @@ -2339,7 +2361,7 @@ void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry, * of the ppc or ppc64 one */ if ((val & PPC4XX_TLBHI_V) && tlb->size < TARGET_PAGE_SIZE) { - cpu_abort(env, "TLB size " TARGET_FMT_lu " < %u " + cpu_abort(cs, "TLB size " TARGET_FMT_lu " < %u " "are not supported (%d)\n", tlb->size, TARGET_PAGE_SIZE, (int)((val >> 7) & 0x7)); } @@ -2348,7 +2370,7 @@ void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry, tlb->prot |= PAGE_VALID; if (val & PPC4XX_TLBHI_E) { /* XXX: TO BE FIXED */ - cpu_abort(env, + cpu_abort(cs, "Little-endian TLB entries are not supported by now\n"); } } else { @@ -2368,7 +2390,7 @@ void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry, LOG_SWTLB("%s: invalidate TLB %d start " TARGET_FMT_lx " end " TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end); for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) { - tlb_flush_page(env, page); + tlb_flush_page(cs, page); } } } @@ -2409,6 +2431,7 @@ target_ulong helper_4xx_tlbsx(CPUPPCState *env, target_ulong address) void helper_440_tlbwe(CPUPPCState *env, uint32_t word, target_ulong entry, target_ulong value) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); ppcemb_tlb_t *tlb; target_ulong EPN, RPN, size; int do_flush_tlbs; @@ -2444,13 +2467,13 @@ void helper_440_tlbwe(CPUPPCState *env, uint32_t word, target_ulong entry, } tlb->PID = env->spr[SPR_440_MMUCR] & 0x000000FF; if (do_flush_tlbs) { - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } break; case 1: RPN = value & 0xFFFFFC0F; if ((tlb->prot & PAGE_VALID) && tlb->RPN != RPN) { - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } tlb->RPN = RPN; break; @@ -2544,6 +2567,7 @@ target_ulong helper_440_tlbsx(CPUPPCState *env, target_ulong address) static ppcmas_tlb_t *booke206_cur_tlb(CPUPPCState *env) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); uint32_t tlbncfg = 0; int esel = (env->spr[SPR_BOOKE_MAS0] & MAS0_ESEL_MASK) >> MAS0_ESEL_SHIFT; int ea = (env->spr[SPR_BOOKE_MAS2] & MAS2_EPN_MASK); @@ -2553,7 +2577,7 @@ static ppcmas_tlb_t *booke206_cur_tlb(CPUPPCState *env) tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlb]; if ((tlbncfg & TLBnCFG_HES) && (env->spr[SPR_BOOKE_MAS0] & MAS0_HES)) { - cpu_abort(env, "we don't support HES yet\n"); + cpu_abort(CPU(cpu), "we don't support HES yet\n"); } return booke206_get_tlbm(env, tlb, ea, esel); @@ -2561,13 +2585,16 @@ static ppcmas_tlb_t *booke206_cur_tlb(CPUPPCState *env) void helper_booke_setpid(CPUPPCState *env, uint32_t pidn, target_ulong pid) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); + env->spr[pidn] = pid; /* changing PIDs mean we're in a different address space now */ - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } void helper_booke206_tlbwe(CPUPPCState *env) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); uint32_t tlbncfg, tlbn; ppcmas_tlb_t *tlb; uint32_t size_tlb, size_ps; @@ -2621,7 +2648,7 @@ void helper_booke206_tlbwe(CPUPPCState *env) } if (msr_gs) { - cpu_abort(env, "missing HV implementation\n"); + cpu_abort(CPU(cpu), "missing HV implementation\n"); } tlb->mas7_3 = ((uint64_t)env->spr[SPR_BOOKE_MAS7] << 32) | env->spr[SPR_BOOKE_MAS3]; @@ -2655,9 +2682,9 @@ void helper_booke206_tlbwe(CPUPPCState *env) } if (booke206_tlb_to_page_size(env, tlb) == TARGET_PAGE_SIZE) { - tlb_flush_page(env, tlb->mas2 & MAS2_EPN_MASK); + tlb_flush_page(CPU(cpu), tlb->mas2 & MAS2_EPN_MASK); } else { - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } } @@ -2764,6 +2791,8 @@ static inline void booke206_invalidate_ea_tlb(CPUPPCState *env, int tlbn, void helper_booke206_tlbivax(CPUPPCState *env, target_ulong address) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); + if (address & 0x4) { /* flush all entries */ if (address & 0x8) { @@ -2779,11 +2808,11 @@ void helper_booke206_tlbivax(CPUPPCState *env, target_ulong address) if (address & 0x8) { /* flush TLB1 entries */ booke206_invalidate_ea_tlb(env, 1, address); - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } else { /* flush TLB0 entries */ booke206_invalidate_ea_tlb(env, 0, address); - tlb_flush_page(env, address & MAS2_EPN_MASK); + tlb_flush_page(CPU(cpu), address & MAS2_EPN_MASK); } } @@ -2795,6 +2824,7 @@ void helper_booke206_tlbilx0(CPUPPCState *env, target_ulong address) void helper_booke206_tlbilx1(CPUPPCState *env, target_ulong address) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); int i, j; int tid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID); ppcmas_tlb_t *tlb = env->tlb.tlbm; @@ -2811,11 +2841,12 @@ void helper_booke206_tlbilx1(CPUPPCState *env, target_ulong address) } tlb += booke206_tlb_size(env, i); } - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } void helper_booke206_tlbilx3(CPUPPCState *env, target_ulong address) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); int i, j; ppcmas_tlb_t *tlb; int tid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID); @@ -2851,7 +2882,7 @@ void helper_booke206_tlbilx3(CPUPPCState *env, target_ulong address) tlb->mas1 &= ~MAS1_VALID; } } - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } void helper_booke206_tlbflush(CPUPPCState *env, uint32_t type) @@ -2892,23 +2923,24 @@ void helper_booke206_tlbflush(CPUPPCState *env, uint32_t type) NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) */ /* XXX: fix it to restore all registers */ -void tlb_fill(CPUPPCState *env, target_ulong addr, int is_write, int mmu_idx, +void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { - CPUState *cpu = CPU(ppc_env_get_cpu(env)); - PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); + PowerPCCPU *cpu = POWERPC_CPU(cs); + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); + CPUPPCState *env = &cpu->env; int ret; if (pcc->handle_mmu_fault) { - ret = pcc->handle_mmu_fault(env, addr, is_write, mmu_idx); + ret = pcc->handle_mmu_fault(cpu, addr, is_write, mmu_idx); } else { ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx); } if (unlikely(ret != 0)) { if (likely(retaddr)) { /* now we have a real cpu fault */ - cpu_restore_state(env, retaddr); + cpu_restore_state(cs, retaddr); } - helper_raise_exception_err(env, env->exception_index, env->error_code); + helper_raise_exception_err(env, cs->exception_index, env->error_code); } } diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 91c33dcd1d..e3fcb03c26 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -11377,8 +11377,8 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu, /* Set env in case of segfault during code fetch */ while (ctx.exception == POWERPC_EXCP_NONE && tcg_ctx.gen_opc_ptr < gen_opc_end) { - if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) { - QTAILQ_FOREACH(bp, &env->breakpoints, entry) { + if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) { + QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { if (bp->pc == ctx.nip) { gen_debug_exception(ctxp); break; diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 3eafbb0d1a..7f53c33eaf 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -631,7 +631,7 @@ static inline void _spr_register(CPUPPCState *env, int num, #if defined(CONFIG_KVM) spr->one_reg_id = one_reg_id, #endif - env->spr[num] = initial_value; + env->spr[num] = spr->default_value = initial_value; } /* Generic PowerPC SPRs */ @@ -4432,6 +4432,7 @@ enum fsl_e500_version { static void init_proc_e500 (CPUPPCState *env, int version) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); uint32_t tlbncfg[2]; uint64_t ivor_mask; uint64_t ivpr_mask = 0xFFFF0000ULL; @@ -4490,7 +4491,7 @@ static void init_proc_e500 (CPUPPCState *env, int version) tlbncfg[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 64); break; default: - cpu_abort(env, "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]); + cpu_abort(CPU(cpu), "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]); } #endif /* Cache sizes */ @@ -4507,7 +4508,7 @@ static void init_proc_e500 (CPUPPCState *env, int version) l1cfg0 |= 0x1000000; /* 64 byte cache block size */ break; default: - cpu_abort(env, "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]); + cpu_abort(CPU(cpu), "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]); } gen_spr_BookE206(env, 0x000000DF, tlbncfg); /* XXX : not implemented */ @@ -7172,7 +7173,8 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 | - PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207; + PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | + PPC2_ISA205 | PPC2_ISA207S; pcc->msr_mask = 0x800000000284FF36ULL; pcc->mmu_model = POWERPC_MMU_2_06; #if defined(CONFIG_SOFTMMU) @@ -7433,7 +7435,7 @@ static int create_new_table (opc_handler_t **table, unsigned char idx) { opc_handler_t **tmp; - tmp = g_malloc(0x20 * sizeof(opc_handler_t)); + tmp = g_new(opc_handler_t *, 0x20); fill_new_table(tmp, 0x20); table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT); @@ -7847,6 +7849,12 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) max_smt, kvm_enabled() ? "KVM" : "TCG"); return; } + if (!is_power_of_2(smp_threads)) { + error_setg(errp, "Cannot support %d threads on PPC with %s, " + "threads count must be a power of 2.", + smp_threads, kvm_enabled() ? "KVM" : "TCG"); + return; + } cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt + (cs->cpu_index % smp_threads); @@ -8220,26 +8228,7 @@ static ObjectClass *ppc_cpu_class_by_name(const char *name) PowerPCCPU *cpu_ppc_init(const char *cpu_model) { - PowerPCCPU *cpu; - ObjectClass *oc; - Error *err = NULL; - - oc = ppc_cpu_class_by_name(cpu_model); - if (oc == NULL) { - return NULL; - } - - cpu = POWERPC_CPU(object_new(object_class_get_name(oc))); - - object_property_set_bool(OBJECT(cpu), true, "realized", &err); - if (err != NULL) { - error_report("%s", error_get_pretty(err)); - error_free(err); - object_unref(OBJECT(cpu)); - return NULL; - } - - return cpu; + return POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU, cpu_model)); } /* Sort by PVR, ordering special case "host" last. */ @@ -8384,6 +8373,14 @@ static void ppc_cpu_set_pc(CPUState *cs, vaddr value) cpu->env.nip = value; } +static bool ppc_cpu_has_work(CPUState *cs) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + + return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD); +} + /* CPUClass::reset() */ static void ppc_cpu_reset(CPUState *s) { @@ -8391,6 +8388,7 @@ static void ppc_cpu_reset(CPUState *s) PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); CPUPPCState *env = &cpu->env; target_ulong msr; + int i; pcc->parent_reset(s); @@ -8433,7 +8431,7 @@ static void ppc_cpu_reset(CPUState *s) env->reserve_addr = (target_ulong)-1ULL; /* Be sure no exception or interrupt is pending */ env->pending_interrupts = 0; - env->exception_index = POWERPC_EXCP_NONE; + s->exception_index = POWERPC_EXCP_NONE; env->error_code = 0; #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) @@ -8444,8 +8442,17 @@ static void ppc_cpu_reset(CPUState *s) env->dtl_size = 0; #endif /* TARGET_PPC64 */ + for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) { + ppc_spr_t *spr = &env->spr_cb[i]; + + if (!spr->name) { + continue; + } + env->spr[i] = spr->default_value; + } + /* Flush all TLBs */ - tlb_flush(env, 1); + tlb_flush(s, 1); } static void ppc_cpu_initfn(Object *obj) @@ -8511,13 +8518,16 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data) cc->reset = ppc_cpu_reset; cc->class_by_name = ppc_cpu_class_by_name; + cc->has_work = ppc_cpu_has_work; cc->do_interrupt = ppc_cpu_do_interrupt; cc->dump_state = ppc_cpu_dump_state; cc->dump_statistics = ppc_cpu_dump_statistics; cc->set_pc = ppc_cpu_set_pc; cc->gdb_read_register = ppc_cpu_gdb_read_register; cc->gdb_write_register = ppc_cpu_gdb_write_register; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = ppc_cpu_handle_mmu_fault; +#else cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug; cc->vmsd = &vmstate_ppc_cpu; #if defined(TARGET_PPC64) diff --git a/target-ppc/user_only_helper.c b/target-ppc/user_only_helper.c index 56e686efd1..829f66f504 100644 --- a/target-ppc/user_only_helper.c +++ b/target-ppc/user_only_helper.c @@ -20,9 +20,11 @@ #include "cpu.h" -int cpu_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw, - int mmu_idx) +int ppc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, + int mmu_idx) { + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; int exception, error_code; if (rw == 2) { @@ -37,7 +39,7 @@ int cpu_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw, env->spr[SPR_DAR] = address; env->spr[SPR_DSISR] = error_code; } - env->exception_index = exception; + cs->exception_index = exception; env->error_code = error_code; return 1; |