static inline void ppc6xx_tlb_invalidate_all(CPUPPCState *env)
{
+ PowerPCCPU *cpu = ppc_env_get_cpu(env);
ppc6xx_tlb_t *tlb;
int nr, max;
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,
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;
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
/* 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;
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;
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;
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;
}
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;
tlb += booke206_tlb_size(env, i);
}
- tlb_flush(env, 1);
+ tlb_flush(CPU(cpu), 1);
}
static hwaddr booke206_tlb_to_page_size(CPUPPCState *env,
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);
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
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;
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);
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;
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;
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");
}
/* 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:
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);
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;
}
}
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:
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:
* 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
/* 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) {
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);
}
}
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)
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
}
}
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;
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)
* 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));
}
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 {
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);
}
}
}
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;
}
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;
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);
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);
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;
}
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];
}
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);
}
}
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) {
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);
}
}
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;
}
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);
tlb->mas1 &= ~MAS1_VALID;
}
}
- tlb_flush(env, 1);
+ tlb_flush(CPU(cpu), 1);
}
void helper_booke206_tlbflush(CPUPPCState *env, uint32_t type)