ppc: Fix coding style in helper.c

helper.c will be spilt by the next patches, fix
style issues before that.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
Blue Swirl 2012-05-30 04:23:24 +00:00 committed by Alexander Graf
parent e5f17ac633
commit 4d5ea5e523

View File

@ -1,5 +1,5 @@
/* /*
* PowerPC emulation helpers for qemu. * PowerPC emulation helpers for QEMU.
* *
* Copyright (c) 2003-2007 Jocelyn Mayer * Copyright (c) 2003-2007 Jocelyn Mayer
* *
@ -84,8 +84,9 @@ int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw,
} else { } else {
exception = POWERPC_EXCP_DSI; exception = POWERPC_EXCP_DSI;
error_code = 0x40000000; error_code = 0x40000000;
if (rw) if (rw) {
error_code |= 0x02000000; error_code |= 0x02000000;
}
env->spr[SPR_DAR] = address; env->spr[SPR_DAR] = address;
env->spr[SPR_DSISR] = error_code; env->spr[SPR_DSISR] = error_code;
} }
@ -160,8 +161,9 @@ static inline int pp_check(int key, int pp, int nx)
break; break;
} }
} }
if (nx == 0) if (nx == 0) {
access |= PAGE_EXEC; access |= PAGE_EXEC;
}
return access; return access;
} }
@ -171,26 +173,29 @@ static inline int check_prot(int prot, int rw, int access_type)
int ret; int ret;
if (access_type == ACCESS_CODE) { if (access_type == ACCESS_CODE) {
if (prot & PAGE_EXEC) if (prot & PAGE_EXEC) {
ret = 0; ret = 0;
else
ret = -2;
} else if (rw) {
if (prot & PAGE_WRITE)
ret = 0;
else
ret = -2;
} else { } else {
if (prot & PAGE_READ)
ret = 0;
else
ret = -2; ret = -2;
} }
} else if (rw) {
if (prot & PAGE_WRITE) {
ret = 0;
} else {
ret = -2;
}
} else {
if (prot & PAGE_READ) {
ret = 0;
} else {
ret = -2;
}
}
return ret; return ret;
} }
static inline int _pte_check(mmu_ctx_t *ctx, int is_64b, target_ulong pte0, static inline int pte_check(mmu_ctx_t *ctx, int is_64b, target_ulong pte0,
target_ulong pte1, int h, int rw, int type) target_ulong pte1, int h, int rw, int type)
{ {
target_ulong ptem, mmask; target_ulong ptem, mmask;
@ -254,14 +259,14 @@ static inline int _pte_check(mmu_ctx_t *ctx, int is_64b, target_ulong pte0,
static inline int pte32_check(mmu_ctx_t *ctx, target_ulong pte0, static inline int pte32_check(mmu_ctx_t *ctx, target_ulong pte0,
target_ulong pte1, int h, int rw, int type) target_ulong pte1, int h, int rw, int type)
{ {
return _pte_check(ctx, 0, pte0, pte1, h, rw, type); return pte_check(ctx, 0, pte0, pte1, h, rw, type);
} }
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
static inline int pte64_check(mmu_ctx_t *ctx, target_ulong pte0, static inline int pte64_check(mmu_ctx_t *ctx, target_ulong pte0,
target_ulong pte1, int h, int rw, int type) target_ulong pte1, int h, int rw, int type)
{ {
return _pte_check(ctx, 1, pte0, pte1, h, rw, type); return pte_check(ctx, 1, pte0, pte1, h, rw, type);
} }
#endif #endif
@ -291,8 +296,8 @@ static inline int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
} }
/* Software driven TLB helpers */ /* Software driven TLB helpers */
static inline int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr, int way, static inline int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
int is_code) int way, int is_code)
{ {
int nr; int nr;
@ -301,8 +306,9 @@ static inline int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr, int wa
/* Select TLB way */ /* Select TLB way */
nr += env->tlb_per_way * way; nr += env->tlb_per_way * way;
/* 6xx have separate TLBs for instructions and data */ /* 6xx have separate TLBs for instructions and data */
if (is_code && env->id_tlbs == 1) if (is_code && env->id_tlbs == 1) {
nr += env->nb_tlb; nr += env->nb_tlb;
}
return nr; return nr;
} }
@ -312,11 +318,12 @@ static inline void ppc6xx_tlb_invalidate_all(CPUPPCState *env)
ppc6xx_tlb_t *tlb; ppc6xx_tlb_t *tlb;
int nr, max; int nr, max;
//LOG_SWTLB("Invalidate all TLBs\n"); /* LOG_SWTLB("Invalidate all TLBs\n"); */
/* Invalidate all defined software TLB */ /* Invalidate all defined software TLB */
max = env->nb_tlb; max = env->nb_tlb;
if (env->id_tlbs == 1) if (env->id_tlbs == 1) {
max *= 2; max *= 2;
}
for (nr = 0; nr < max; nr++) { for (nr = 0; nr < max; nr++) {
tlb = &env->tlb.tlb6[nr]; tlb = &env->tlb.tlb6[nr];
pte_invalidate(&tlb->pte0); pte_invalidate(&tlb->pte0);
@ -324,7 +331,7 @@ static inline void ppc6xx_tlb_invalidate_all(CPUPPCState *env)
tlb_flush(env, 1); tlb_flush(env, 1);
} }
static inline void __ppc6xx_tlb_invalidate_virt(CPUPPCState *env, static inline void ppc6xx_tlb_invalidate_virt2(CPUPPCState *env,
target_ulong eaddr, target_ulong eaddr,
int is_code, int match_epn) int is_code, int match_epn)
{ {
@ -352,7 +359,7 @@ static inline void __ppc6xx_tlb_invalidate_virt(CPUPPCState *env,
static inline void ppc6xx_tlb_invalidate_virt(CPUPPCState *env, static inline void ppc6xx_tlb_invalidate_virt(CPUPPCState *env,
target_ulong eaddr, int is_code) target_ulong eaddr, int is_code)
{ {
__ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0); ppc6xx_tlb_invalidate_virt2(env, eaddr, is_code, 0);
} }
void ppc6xx_tlb_store(CPUPPCState *env, target_ulong EPN, int way, int is_code, void ppc6xx_tlb_store(CPUPPCState *env, target_ulong EPN, int way, int is_code,
@ -366,7 +373,7 @@ void ppc6xx_tlb_store (CPUPPCState *env, target_ulong EPN, int way, int is_code,
LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx
" PTE1 " TARGET_FMT_lx "\n", nr, env->nb_tlb, EPN, pte0, pte1); " PTE1 " TARGET_FMT_lx "\n", nr, env->nb_tlb, EPN, pte0, pte1);
/* Invalidate any pending reference in QEMU for this virtual address */ /* Invalidate any pending reference in QEMU for this virtual address */
__ppc6xx_tlb_invalidate_virt(env, EPN, is_code, 1); ppc6xx_tlb_invalidate_virt2(env, EPN, is_code, 1);
tlb->pte0 = pte0; tlb->pte0 = pte0;
tlb->pte1 = pte1; tlb->pte1 = pte1;
tlb->EPN = EPN; tlb->EPN = EPN;
@ -436,8 +443,8 @@ static inline int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx,
} }
/* Perform BAT hit & translation */ /* Perform BAT hit & translation */
static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp, int *validp, static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp,
int *protp, target_ulong *BATu, int *validp, int *protp, target_ulong *BATu,
target_ulong *BATl) target_ulong *BATl)
{ {
target_ulong bl; target_ulong bl;
@ -452,10 +459,11 @@ static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp, int *valid
pp = *BATl & 0x00000003; pp = *BATl & 0x00000003;
if (pp != 0) { if (pp != 0) {
prot = PAGE_READ | PAGE_EXEC; prot = PAGE_READ | PAGE_EXEC;
if (pp == 0x2) if (pp == 0x2) {
prot |= PAGE_WRITE; prot |= PAGE_WRITE;
} }
} }
}
*blp = bl; *blp = bl;
*validp = valid; *validp = valid;
*protp = prot; *protp = prot;
@ -475,10 +483,11 @@ static inline void bat_601_size_prot(CPUPPCState *env, target_ulong *blp,
valid = (*BATl >> 6) & 1; valid = (*BATl >> 6) & 1;
if (valid) { if (valid) {
pp = *BATu & 0x00000003; pp = *BATu & 0x00000003;
if (msr_pr == 0) if (msr_pr == 0) {
key = (*BATu >> 3) & 1; key = (*BATu >> 3) & 1;
else } else {
key = (*BATu >> 2) & 1; key = (*BATu >> 2) & 1;
}
prot = pp_check(key, pp, 0); prot = pp_check(key, pp, 0);
} }
*blp = bl; *blp = bl;
@ -486,8 +495,8 @@ static inline void bat_601_size_prot(CPUPPCState *env, target_ulong *blp,
*protp = prot; *protp = prot;
} }
static inline int get_bat(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong virtual, static inline int get_bat(CPUPPCState *env, mmu_ctx_t *ctx,
int rw, int type) target_ulong virtual, int rw, int type)
{ {
target_ulong *BATlt, *BATut, *BATu, *BATl; target_ulong *BATlt, *BATut, *BATu, *BATl;
target_ulong BEPIl, BEPIu, bl; target_ulong BEPIl, BEPIu, bl;
@ -530,10 +539,11 @@ static inline int get_bat(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong virtual
/* Compute access rights */ /* Compute access rights */
ctx->prot = prot; ctx->prot = prot;
ret = check_prot(ctx->prot, rw, type); ret = check_prot(ctx->prot, rw, type);
if (ret == 0) if (ret == 0) {
LOG_BATS("BAT %d match: r " TARGET_FMT_plx " prot=%c%c\n", LOG_BATS("BAT %d match: r " TARGET_FMT_plx " prot=%c%c\n",
i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-', i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-',
ctx->prot & PAGE_WRITE ? 'W' : '-'); ctx->prot & PAGE_WRITE ? 'W' : '-');
}
break; break;
} }
} }
@ -569,7 +579,7 @@ static inline target_phys_addr_t get_pteg_offset(CPUPPCState *env,
} }
/* PTE table lookup */ /* PTE table lookup */
static inline int _find_pte(CPUPPCState *env, mmu_ctx_t *ctx, int is_64b, int h, static inline int find_pte2(CPUPPCState *env, mmu_ctx_t *ctx, int is_64b, int h,
int rw, int type, int target_page_bits) int rw, int type, int target_page_bits)
{ {
target_phys_addr_t pteg_off; target_phys_addr_t pteg_off;
@ -679,11 +689,12 @@ static inline int find_pte(CPUPPCState *env, mmu_ctx_t *ctx, int h, int rw,
int type, int target_page_bits) int type, int target_page_bits)
{ {
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
if (env->mmu_model & POWERPC_MMU_64) if (env->mmu_model & POWERPC_MMU_64) {
return _find_pte(env, ctx, 1, h, rw, type, target_page_bits); return find_pte2(env, ctx, 1, h, rw, type, target_page_bits);
}
#endif #endif
return _find_pte(env, ctx, 0, h, rw, type, target_page_bits); return find_pte2(env, ctx, 0, h, rw, type, target_page_bits);
} }
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
@ -734,9 +745,10 @@ void ppc_slb_invalidate_all (CPUPPCState *env)
do_invalidate = 1; do_invalidate = 1;
} }
} }
if (do_invalidate) if (do_invalidate) {
tlb_flush(env, 1); tlb_flush(env, 1);
} }
}
void ppc_slb_invalidate_one(CPUPPCState *env, uint64_t T0) void ppc_slb_invalidate_one(CPUPPCState *env, uint64_t T0)
{ {
@ -909,21 +921,24 @@ static inline int get_segment(CPUPPCState *env, mmu_ctx_t *ctx,
ret = find_pte(env, ctx, 0, rw, type, target_page_bits); ret = find_pte(env, ctx, 0, rw, type, target_page_bits);
if (ret < 0) { if (ret < 0) {
/* Secondary table lookup */ /* Secondary table lookup */
if (eaddr != 0xEFFFFFFF) if (eaddr != 0xEFFFFFFF) {
LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
" vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
" hash=" TARGET_FMT_plx "\n", env->htab_base, " hash=" TARGET_FMT_plx "\n", env->htab_base,
env->htab_mask, vsid, ctx->ptem, ctx->hash[1]); env->htab_mask, vsid, ctx->ptem, ctx->hash[1]);
}
ret2 = find_pte(env, ctx, 1, rw, type, ret2 = find_pte(env, ctx, 1, rw, type,
target_page_bits); target_page_bits);
if (ret2 != -1) if (ret2 != -1) {
ret = ret2; ret = ret2;
} }
} }
}
#if defined(DUMP_PAGE_TABLES) #if defined(DUMP_PAGE_TABLES)
if (qemu_log_enabled()) { if (qemu_log_enabled()) {
target_phys_addr_t curaddr; target_phys_addr_t curaddr;
uint32_t a0, a1, a2, a3; uint32_t a0, a1, a2, a3;
qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx
"\n", sdr, mask + 0x80); "\n", sdr, mask + 0x80);
for (curaddr = sdr; curaddr < (sdr + mask + 0x80); for (curaddr = sdr; curaddr < (sdr + mask + 0x80);
@ -945,6 +960,7 @@ static inline int get_segment(CPUPPCState *env, mmu_ctx_t *ctx,
} }
} else { } else {
target_ulong sr; target_ulong sr;
LOG_MMU("direct store...\n"); LOG_MMU("direct store...\n");
/* Direct-store segment : absolutely *BUGGY* for now */ /* Direct-store segment : absolutely *BUGGY* for now */
@ -1018,11 +1034,13 @@ int ppcemb_tlb_check(CPUPPCState *env, ppcemb_tlb_t *tlb,
" " TARGET_FMT_lx " %u %x\n", __func__, i, address, pid, tlb->EPN, " " TARGET_FMT_lx " %u %x\n", __func__, i, address, pid, tlb->EPN,
mask, (uint32_t)tlb->PID, tlb->prot); mask, (uint32_t)tlb->PID, tlb->prot);
/* Check PID */ /* Check PID */
if (tlb->PID != 0 && tlb->PID != pid) if (tlb->PID != 0 && tlb->PID != pid) {
return -1; return -1;
}
/* Check effective address */ /* Check effective address */
if ((address & mask) != tlb->EPN) if ((address & mask) != tlb->EPN) {
return -1; return -1;
}
*raddrp = (tlb->RPN & mask) | (address & ~mask); *raddrp = (tlb->RPN & mask) | (address & ~mask);
#if (TARGET_PHYS_ADDR_BITS >= 36) #if (TARGET_PHYS_ADDR_BITS >= 36)
if (ext) { if (ext) {
@ -1080,8 +1098,9 @@ static inline void ppc4xx_tlb_invalidate_virt(CPUPPCState *env,
tlb = &env->tlb.tlbe[i]; tlb = &env->tlb.tlbe[i];
if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) { if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) {
end = tlb->EPN + tlb->size; end = tlb->EPN + tlb->size;
for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) {
tlb_flush_page(env, page); tlb_flush_page(env, page);
}
tlb->prot &= ~PAGE_VALID; tlb->prot &= ~PAGE_VALID;
break; break;
} }
@ -1092,7 +1111,8 @@ static inline void ppc4xx_tlb_invalidate_virt(CPUPPCState *env,
} }
static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
target_ulong address, int rw, int access_type) target_ulong address, int rw,
int access_type)
{ {
ppcemb_tlb_t *tlb; ppcemb_tlb_t *tlb;
target_phys_addr_t raddr; target_phys_addr_t raddr;
@ -1104,8 +1124,9 @@ static int mmu40x_get_physical_address (CPUPPCState *env, mmu_ctx_t *ctx,
for (i = 0; i < env->nb_tlb; i++) { for (i = 0; i < env->nb_tlb; i++) {
tlb = &env->tlb.tlbe[i]; tlb = &env->tlb.tlbe[i];
if (ppcemb_tlb_check(env, tlb, &raddr, address, if (ppcemb_tlb_check(env, tlb, &raddr, address,
env->spr[SPR_40x_PID], 0, i) < 0) env->spr[SPR_40x_PID], 0, i) < 0) {
continue; continue;
}
zsel = (tlb->attr >> 4) & 0xF; zsel = (tlb->attr >> 4) & 0xF;
zpr = (env->spr[SPR_40x_ZPR] >> (30 - (2 * zsel))) & 0x3; zpr = (env->spr[SPR_40x_ZPR] >> (30 - (2 * zsel))) & 0x3;
LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n", LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
@ -1113,8 +1134,9 @@ static int mmu40x_get_physical_address (CPUPPCState *env, mmu_ctx_t *ctx,
/* Check execute enable bit */ /* Check execute enable bit */
switch (zpr) { switch (zpr) {
case 0x2: case 0x2:
if (pr != 0) if (pr != 0) {
goto check_perms; goto check_perms;
}
/* No break here */ /* No break here */
case 0x3: case 0x3:
/* All accesses granted */ /* All accesses granted */
@ -1135,8 +1157,9 @@ static int mmu40x_get_physical_address (CPUPPCState *env, mmu_ctx_t *ctx,
/* Check from TLB entry */ /* Check from TLB entry */
ctx->prot = tlb->prot; ctx->prot = tlb->prot;
ret = check_prot(ctx->prot, rw, access_type); ret = check_prot(ctx->prot, rw, access_type);
if (ret == -2) if (ret == -2) {
env->spr[SPR_40x_ESR] = 0; env->spr[SPR_40x_ESR] = 0;
}
break; break;
} }
if (ret >= 0) { if (ret >= 0) {
@ -1167,7 +1190,7 @@ static inline int mmubooke_check_tlb (CPUPPCState *env, ppcemb_tlb_t *tlb,
target_ulong address, int rw, target_ulong address, int rw,
int access_type, int i) int access_type, int i)
{ {
int ret, _prot; int ret, prot2;
if (ppcemb_tlb_check(env, tlb, raddr, address, if (ppcemb_tlb_check(env, tlb, raddr, address,
env->spr[SPR_BOOKE_PID], env->spr[SPR_BOOKE_PID],
@ -1193,9 +1216,9 @@ static inline int mmubooke_check_tlb (CPUPPCState *env, ppcemb_tlb_t *tlb,
found_tlb: found_tlb:
if (msr_pr != 0) { if (msr_pr != 0) {
_prot = tlb->prot & 0xF; prot2 = tlb->prot & 0xF;
} else { } else {
_prot = (tlb->prot >> 4) & 0xF; prot2 = (tlb->prot >> 4) & 0xF;
} }
/* Check the address space */ /* Check the address space */
@ -1205,13 +1228,13 @@ found_tlb:
return -1; return -1;
} }
*prot = _prot; *prot = prot2;
if (_prot & PAGE_EXEC) { if (prot2 & PAGE_EXEC) {
LOG_SWTLB("%s: good TLB!\n", __func__); LOG_SWTLB("%s: good TLB!\n", __func__);
return 0; return 0;
} }
LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, _prot); LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, prot2);
ret = -3; ret = -3;
} else { } else {
if (msr_dr != (tlb->attr & 1)) { if (msr_dr != (tlb->attr & 1)) {
@ -1219,13 +1242,13 @@ found_tlb:
return -1; return -1;
} }
*prot = _prot; *prot = prot2;
if ((!rw && _prot & PAGE_READ) || (rw && (_prot & PAGE_WRITE))) { if ((!rw && prot2 & PAGE_READ) || (rw && (prot2 & PAGE_WRITE))) {
LOG_SWTLB("%s: found TLB!\n", __func__); LOG_SWTLB("%s: found TLB!\n", __func__);
return 0; return 0;
} }
LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, _prot); LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, prot2);
ret = -2; ret = -2;
} }
@ -1285,7 +1308,8 @@ void booke206_flush_tlb(CPUPPCState *env, int flags, const int check_iprot)
tlb_flush(env, 1); tlb_flush(env, 1);
} }
target_phys_addr_t booke206_tlb_to_page_size(CPUPPCState *env, ppcmas_tlb_t *tlb) target_phys_addr_t booke206_tlb_to_page_size(CPUPPCState *env,
ppcmas_tlb_t *tlb)
{ {
int tlbm_size; int tlbm_size;
@ -1337,7 +1361,7 @@ static int mmubooke206_check_tlb(CPUPPCState *env, ppcmas_tlb_t *tlb,
int access_type) int access_type)
{ {
int ret; int ret;
int _prot = 0; int prot2 = 0;
if (ppcmas_tlb_check(env, tlb, raddr, address, if (ppcmas_tlb_check(env, tlb, raddr, address,
env->spr[SPR_BOOKE_PID]) >= 0) { env->spr[SPR_BOOKE_PID]) >= 0) {
@ -1363,23 +1387,23 @@ found_tlb:
if (msr_pr != 0) { if (msr_pr != 0) {
if (tlb->mas7_3 & MAS3_UR) { if (tlb->mas7_3 & MAS3_UR) {
_prot |= PAGE_READ; prot2 |= PAGE_READ;
} }
if (tlb->mas7_3 & MAS3_UW) { if (tlb->mas7_3 & MAS3_UW) {
_prot |= PAGE_WRITE; prot2 |= PAGE_WRITE;
} }
if (tlb->mas7_3 & MAS3_UX) { if (tlb->mas7_3 & MAS3_UX) {
_prot |= PAGE_EXEC; prot2 |= PAGE_EXEC;
} }
} else { } else {
if (tlb->mas7_3 & MAS3_SR) { if (tlb->mas7_3 & MAS3_SR) {
_prot |= PAGE_READ; prot2 |= PAGE_READ;
} }
if (tlb->mas7_3 & MAS3_SW) { if (tlb->mas7_3 & MAS3_SW) {
_prot |= PAGE_WRITE; prot2 |= PAGE_WRITE;
} }
if (tlb->mas7_3 & MAS3_SX) { if (tlb->mas7_3 & MAS3_SX) {
_prot |= PAGE_EXEC; prot2 |= PAGE_EXEC;
} }
} }
@ -1390,13 +1414,13 @@ found_tlb:
return -1; return -1;
} }
*prot = _prot; *prot = prot2;
if (_prot & PAGE_EXEC) { if (prot2 & PAGE_EXEC) {
LOG_SWTLB("%s: good TLB!\n", __func__); LOG_SWTLB("%s: good TLB!\n", __func__);
return 0; return 0;
} }
LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, _prot); LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, prot2);
ret = -3; ret = -3;
} else { } else {
if (msr_dr != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) { if (msr_dr != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
@ -1404,13 +1428,13 @@ found_tlb:
return -1; return -1;
} }
*prot = _prot; *prot = prot2;
if ((!rw && _prot & PAGE_READ) || (rw && (_prot & PAGE_WRITE))) { if ((!rw && prot2 & PAGE_READ) || (rw && (prot2 & PAGE_WRITE))) {
LOG_SWTLB("%s: found TLB!\n", __func__); LOG_SWTLB("%s: found TLB!\n", __func__);
return 0; return 0;
} }
LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, _prot); LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, prot2);
ret = -2; ret = -2;
} }
@ -1521,7 +1545,8 @@ static void mmubooke206_dump_one_tlb(FILE *f, fprintf_function cpu_fprintf,
int i; int i;
cpu_fprintf(f, "\nTLB%d:\n", tlbn); cpu_fprintf(f, "\nTLB%d:\n", tlbn);
cpu_fprintf(f, "Effective Physical Size TID TS SRWX URWX WIMGE U0123\n"); cpu_fprintf(f, "Effective Physical Size TID TS SRWX"
" URWX WIMGE U0123\n");
entry = &env->tlb.tlbm[offset]; entry = &env->tlb.tlbm[offset];
for (i = 0; i < tlbsize; i++, entry++) { for (i = 0; i < tlbsize; i++, entry++) {
@ -1537,7 +1562,8 @@ static void mmubooke206_dump_one_tlb(FILE *f, fprintf_function cpu_fprintf,
ea = entry->mas2 & ~(size - 1); ea = entry->mas2 & ~(size - 1);
pa = entry->mas7_3 & ~(size - 1); pa = entry->mas7_3 & ~(size - 1);
cpu_fprintf(f, "0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u S%c%c%c U%c%c%c %c%c%c%c%c U%c%c%c%c\n", cpu_fprintf(f, "0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u S%c%c%c"
"U%c%c%c %c%c%c%c%c U%c%c%c%c\n",
(uint64_t)ea, (uint64_t)pa, (uint64_t)ea, (uint64_t)pa,
book3e_tsize_to_str[tsize], book3e_tsize_to_str[tsize],
(entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT, (entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT,
@ -1721,8 +1747,9 @@ int get_physical_address (CPUPPCState *env, mmu_ctx_t *ctx, target_ulong eaddr,
case POWERPC_MMU_SOFT_6xx: case POWERPC_MMU_SOFT_6xx:
case POWERPC_MMU_SOFT_74xx: case POWERPC_MMU_SOFT_74xx:
/* Try to find a BAT */ /* Try to find a BAT */
if (env->nb_BATs != 0) if (env->nb_BATs != 0) {
ret = get_bat(env, ctx, eaddr, rw, access_type); ret = get_bat(env, ctx, eaddr, rw, access_type);
}
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
case POWERPC_MMU_620: case POWERPC_MMU_620:
case POWERPC_MMU_64B: case POWERPC_MMU_64B:
@ -1770,8 +1797,9 @@ target_phys_addr_t cpu_get_phys_page_debug (CPUPPCState *env, target_ulong addr)
{ {
mmu_ctx_t ctx; mmu_ctx_t ctx;
if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0)) if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0)) {
return -1; return -1;
}
return ctx.raddr & TARGET_PAGE_MASK; return ctx.raddr & TARGET_PAGE_MASK;
} }
@ -1966,10 +1994,11 @@ int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw,
env->exception_index = POWERPC_EXCP_DTLB; env->exception_index = POWERPC_EXCP_DTLB;
env->error_code = 0; env->error_code = 0;
env->spr[SPR_40x_DEAR] = address; env->spr[SPR_40x_DEAR] = address;
if (rw) if (rw) {
env->spr[SPR_40x_ESR] = 0x00800000; env->spr[SPR_40x_ESR] = 0x00800000;
else } else {
env->spr[SPR_40x_ESR] = 0x00000000; env->spr[SPR_40x_ESR] = 0x00000000;
}
break; break;
case POWERPC_MMU_32B: case POWERPC_MMU_32B:
case POWERPC_MMU_601: case POWERPC_MMU_601:
@ -1981,10 +2010,11 @@ int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw,
env->exception_index = POWERPC_EXCP_DSI; env->exception_index = POWERPC_EXCP_DSI;
env->error_code = 0; env->error_code = 0;
env->spr[SPR_DAR] = address; env->spr[SPR_DAR] = address;
if (rw == 1) if (rw == 1) {
env->spr[SPR_DSISR] = 0x42000000; env->spr[SPR_DSISR] = 0x42000000;
else } else {
env->spr[SPR_DSISR] = 0x40000000; env->spr[SPR_DSISR] = 0x40000000;
}
break; break;
case POWERPC_MMU_MPC8xx: case POWERPC_MMU_MPC8xx:
/* XXX: TODO */ /* XXX: TODO */
@ -2045,20 +2075,22 @@ int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw,
env->exception_index = POWERPC_EXCP_DSI; env->exception_index = POWERPC_EXCP_DSI;
env->error_code = 0; env->error_code = 0;
env->spr[SPR_DAR] = address; env->spr[SPR_DAR] = address;
if (rw == 1) if (rw == 1) {
env->spr[SPR_DSISR] = 0x06000000; env->spr[SPR_DSISR] = 0x06000000;
else } else {
env->spr[SPR_DSISR] = 0x04000000; env->spr[SPR_DSISR] = 0x04000000;
}
break; break;
case ACCESS_EXT: case ACCESS_EXT:
/* eciwx or ecowx */ /* eciwx or ecowx */
env->exception_index = POWERPC_EXCP_DSI; env->exception_index = POWERPC_EXCP_DSI;
env->error_code = 0; env->error_code = 0;
env->spr[SPR_DAR] = address; env->spr[SPR_DAR] = address;
if (rw == 1) if (rw == 1) {
env->spr[SPR_DSISR] = 0x06100000; env->spr[SPR_DSISR] = 0x06100000;
else } else {
env->spr[SPR_DSISR] = 0x04100000; env->spr[SPR_DSISR] = 0x04100000;
}
break; break;
default: default:
printf("DSI: invalid exception (%d)\n", ret); printf("DSI: invalid exception (%d)\n", ret);
@ -2077,10 +2109,11 @@ int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw,
env->error_code = 0; env->error_code = 0;
env->spr[SPR_DAR] = address; env->spr[SPR_DAR] = address;
/* XXX: this might be incorrect */ /* XXX: this might be incorrect */
if (rw == 1) if (rw == 1) {
env->spr[SPR_DSISR] = 0x42000000; env->spr[SPR_DSISR] = 0x42000000;
else } else {
env->spr[SPR_DSISR] = 0x40000000; env->spr[SPR_DSISR] = 0x40000000;
}
} else { } else {
env->exception_index = POWERPC_EXCP_DSEG; env->exception_index = POWERPC_EXCP_DSEG;
env->error_code = 0; env->error_code = 0;
@ -2112,8 +2145,9 @@ static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu,
end = base + mask + 0x00020000; end = base + mask + 0x00020000;
LOG_BATS("Flush BAT from " TARGET_FMT_lx " to " TARGET_FMT_lx " (" LOG_BATS("Flush BAT from " TARGET_FMT_lx " to " TARGET_FMT_lx " ("
TARGET_FMT_lx ")\n", base, end, mask); TARGET_FMT_lx ")\n", base, end, mask);
for (page = base; page != end; page += TARGET_PAGE_SIZE) for (page = base; page != end; page += TARGET_PAGE_SIZE) {
tlb_flush_page(env, page); tlb_flush_page(env, page);
}
LOG_BATS("Flush done\n"); LOG_BATS("Flush done\n");
} }
#endif #endif
@ -2224,8 +2258,9 @@ void ppc_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value)
#endif #endif
} }
#if defined(FLUSH_ALL_TLBS) #if defined(FLUSH_ALL_TLBS)
if (do_inval) if (do_inval) {
tlb_flush(env, 1); tlb_flush(env, 1);
}
#endif #endif
} }
} }
@ -2261,8 +2296,9 @@ void ppc_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value)
env->IBAT[1][nr] = value; env->IBAT[1][nr] = value;
env->DBAT[1][nr] = value; env->DBAT[1][nr] = value;
#if defined(FLUSH_ALL_TLBS) #if defined(FLUSH_ALL_TLBS)
if (do_inval) if (do_inval) {
tlb_flush(env, 1); tlb_flush(env, 1);
}
#endif #endif
} }
} }
@ -2317,8 +2353,9 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
case POWERPC_MMU_SOFT_6xx: case POWERPC_MMU_SOFT_6xx:
case POWERPC_MMU_SOFT_74xx: case POWERPC_MMU_SOFT_74xx:
ppc6xx_tlb_invalidate_virt(env, addr, 0); ppc6xx_tlb_invalidate_virt(env, addr, 0);
if (env->id_tlbs == 1) if (env->id_tlbs == 1) {
ppc6xx_tlb_invalidate_virt(env, addr, 1); ppc6xx_tlb_invalidate_virt(env, addr, 1);
}
break; break;
case POWERPC_MMU_SOFT_4xx: case POWERPC_MMU_SOFT_4xx:
case POWERPC_MMU_SOFT_4xx_Z: case POWERPC_MMU_SOFT_4xx_Z:
@ -2427,7 +2464,7 @@ void ppc_store_sdr1 (CPUPPCState *env, target_ulong value)
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
target_ulong ppc_load_sr(CPUPPCState *env, int slb_nr) target_ulong ppc_load_sr(CPUPPCState *env, int slb_nr)
{ {
// XXX /* XXX */
return 0; return 0;
} }
#endif #endif
@ -2465,9 +2502,10 @@ void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value)
/* Invalidate 256 MB of virtual memory */ /* Invalidate 256 MB of virtual memory */
page = (16 << 20) * srnum; page = (16 << 20) * srnum;
end = page + (16 << 20); end = page + (16 << 20);
for (; page != end; page += TARGET_PAGE_SIZE) for (; page != end; page += TARGET_PAGE_SIZE) {
tlb_flush_page(env, page); tlb_flush_page(env, page);
} }
}
#else #else
tlb_flush(env, 1); tlb_flush(env, 1);
#endif #endif
@ -2602,23 +2640,27 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
case POWERPC_EXCP_DSI: /* Data storage exception */ case POWERPC_EXCP_DSI: /* Data storage exception */
LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx
"\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]); "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
if (lpes1 == 0) if (lpes1 == 0) {
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
goto store_next; goto store_next;
case POWERPC_EXCP_ISI: /* Instruction storage exception */ case POWERPC_EXCP_ISI: /* Instruction storage exception */
LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx
"\n", msr, env->nip); "\n", msr, env->nip);
if (lpes1 == 0) if (lpes1 == 0) {
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
msr |= env->error_code; msr |= env->error_code;
goto store_next; goto store_next;
case POWERPC_EXCP_EXTERNAL: /* External input */ case POWERPC_EXCP_EXTERNAL: /* External input */
if (lpes0 == 1) if (lpes0 == 1) {
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
goto store_next; goto store_next;
case POWERPC_EXCP_ALIGN: /* Alignment exception */ case POWERPC_EXCP_ALIGN: /* Alignment exception */
if (lpes1 == 0) if (lpes1 == 0) {
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
/* XXX: this is false */ /* XXX: this is false */
/* Get rS/rD and rA from faulting opcode */ /* Get rS/rD and rA from faulting opcode */
env->spr[SPR_DSISR] |= (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16; env->spr[SPR_DSISR] |= (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
@ -2632,29 +2674,34 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
env->error_code = 0; env->error_code = 0;
return; return;
} }
if (lpes1 == 0) if (lpes1 == 0) {
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
msr |= 0x00100000; msr |= 0x00100000;
if (msr_fe0 == msr_fe1) if (msr_fe0 == msr_fe1) {
goto store_next; goto store_next;
}
msr |= 0x00010000; msr |= 0x00010000;
break; break;
case POWERPC_EXCP_INVAL: case POWERPC_EXCP_INVAL:
LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip); LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);
if (lpes1 == 0) if (lpes1 == 0) {
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
msr |= 0x00080000; msr |= 0x00080000;
env->spr[SPR_BOOKE_ESR] = ESR_PIL; env->spr[SPR_BOOKE_ESR] = ESR_PIL;
break; break;
case POWERPC_EXCP_PRIV: case POWERPC_EXCP_PRIV:
if (lpes1 == 0) if (lpes1 == 0) {
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
msr |= 0x00040000; msr |= 0x00040000;
env->spr[SPR_BOOKE_ESR] = ESR_PPR; env->spr[SPR_BOOKE_ESR] = ESR_PPR;
break; break;
case POWERPC_EXCP_TRAP: case POWERPC_EXCP_TRAP:
if (lpes1 == 0) if (lpes1 == 0) {
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
msr |= 0x00020000; msr |= 0x00020000;
env->spr[SPR_BOOKE_ESR] = ESR_PTR; env->spr[SPR_BOOKE_ESR] = ESR_PTR;
break; break;
@ -2666,8 +2713,9 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
} }
goto store_current; goto store_current;
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
if (lpes1 == 0) if (lpes1 == 0) {
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
goto store_current; goto store_current;
case POWERPC_EXCP_SYSCALL: /* System call exception */ case POWERPC_EXCP_SYSCALL: /* System call exception */
dump_syscall(env); dump_syscall(env);
@ -2676,14 +2724,16 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
cpu_ppc_hypercall(env); cpu_ppc_hypercall(env);
return; return;
} }
if (lev == 1 || (lpes0 == 0 && lpes1 == 0)) if (lev == 1 || (lpes0 == 0 && lpes1 == 0)) {
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
goto store_next; goto store_next;
case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */ case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
goto store_current; goto store_current;
case POWERPC_EXCP_DECR: /* Decrementer exception */ case POWERPC_EXCP_DECR: /* Decrementer exception */
if (lpes1 == 0) if (lpes1 == 0) {
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
goto store_next; goto store_next;
case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
/* FIT on 4xx */ /* FIT on 4xx */
@ -2758,12 +2808,14 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
} }
goto store_next; goto store_next;
case POWERPC_EXCP_DSEG: /* Data segment exception */ case POWERPC_EXCP_DSEG: /* Data segment exception */
if (lpes1 == 0) if (lpes1 == 0) {
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
goto store_next; goto store_next;
case POWERPC_EXCP_ISEG: /* Instruction segment exception */ case POWERPC_EXCP_ISEG: /* Instruction segment exception */
if (lpes1 == 0) if (lpes1 == 0) {
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
goto store_next; goto store_next;
case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
srr0 = SPR_HSRR0; srr0 = SPR_HSRR0;
@ -2772,8 +2824,9 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
new_msr |= env->msr & ((target_ulong)1 << MSR_RI); new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
goto store_next; goto store_next;
case POWERPC_EXCP_TRACE: /* Trace exception */ case POWERPC_EXCP_TRACE: /* Trace exception */
if (lpes1 == 0) if (lpes1 == 0) {
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
goto store_next; goto store_next;
case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
srr0 = SPR_HSRR0; srr0 = SPR_HSRR0;
@ -2800,8 +2853,9 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
new_msr |= env->msr & ((target_ulong)1 << MSR_RI); new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
goto store_next; goto store_next;
case POWERPC_EXCP_VPU: /* Vector unavailable exception */ case POWERPC_EXCP_VPU: /* Vector unavailable exception */
if (lpes1 == 0) if (lpes1 == 0) {
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
goto store_current; goto store_current;
case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */ case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */
LOG_EXCP("PIT exception\n"); LOG_EXCP("PIT exception\n");
@ -2820,8 +2874,9 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
"is not implemented yet !\n"); "is not implemented yet !\n");
goto store_next; goto store_next;
case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */ case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
if (lpes1 == 0) /* XXX: check this */ if (lpes1 == 0) { /* XXX: check this */
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
switch (excp_model) { switch (excp_model) {
case POWERPC_EXCP_602: case POWERPC_EXCP_602:
case POWERPC_EXCP_603: case POWERPC_EXCP_603:
@ -2838,8 +2893,9 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
} }
break; break;
case POWERPC_EXCP_DLTLB: /* Data load TLB miss */ case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
if (lpes1 == 0) /* XXX: check this */ if (lpes1 == 0) { /* XXX: check this */
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
switch (excp_model) { switch (excp_model) {
case POWERPC_EXCP_602: case POWERPC_EXCP_602:
case POWERPC_EXCP_603: case POWERPC_EXCP_603:
@ -2856,8 +2912,9 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
} }
break; break;
case POWERPC_EXCP_DSTLB: /* Data store TLB miss */ case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
if (lpes1 == 0) /* XXX: check this */ if (lpes1 == 0) { /* XXX: check this */
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
switch (excp_model) { switch (excp_model) {
case POWERPC_EXCP_602: case POWERPC_EXCP_602:
case POWERPC_EXCP_603: case POWERPC_EXCP_603:
@ -2877,16 +2934,18 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
const char *es; const char *es;
target_ulong *miss, *cmp; target_ulong *miss, *cmp;
int en; int en;
if (excp == POWERPC_EXCP_IFTLB) { if (excp == POWERPC_EXCP_IFTLB) {
es = "I"; es = "I";
en = 'I'; en = 'I';
miss = &env->spr[SPR_IMISS]; miss = &env->spr[SPR_IMISS];
cmp = &env->spr[SPR_ICMP]; cmp = &env->spr[SPR_ICMP];
} else { } else {
if (excp == POWERPC_EXCP_DLTLB) if (excp == POWERPC_EXCP_DLTLB) {
es = "DL"; es = "DL";
else } else {
es = "DS"; es = "DS";
}
en = 'D'; en = 'D';
miss = &env->spr[SPR_DMISS]; miss = &env->spr[SPR_DMISS];
cmp = &env->spr[SPR_DCMP]; cmp = &env->spr[SPR_DCMP];
@ -2910,16 +2969,18 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
const char *es; const char *es;
target_ulong *miss, *cmp; target_ulong *miss, *cmp;
int en; int en;
if (excp == POWERPC_EXCP_IFTLB) { if (excp == POWERPC_EXCP_IFTLB) {
es = "I"; es = "I";
en = 'I'; en = 'I';
miss = &env->spr[SPR_TLBMISS]; miss = &env->spr[SPR_TLBMISS];
cmp = &env->spr[SPR_PTEHI]; cmp = &env->spr[SPR_PTEHI];
} else { } else {
if (excp == POWERPC_EXCP_DLTLB) if (excp == POWERPC_EXCP_DLTLB) {
es = "DL"; es = "DL";
else } else {
es = "DS"; es = "DS";
}
en = 'D'; en = 'D';
miss = &env->spr[SPR_TLBMISS]; miss = &env->spr[SPR_TLBMISS];
cmp = &env->spr[SPR_PTEHI]; cmp = &env->spr[SPR_PTEHI];
@ -2959,8 +3020,9 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
"is not implemented yet !\n"); "is not implemented yet !\n");
goto store_next; goto store_next;
case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */
if (lpes1 == 0) if (lpes1 == 0) {
new_msr |= (target_ulong)MSR_HVB; new_msr |= (target_ulong)MSR_HVB;
}
/* XXX: TODO */ /* XXX: TODO */
cpu_abort(env, cpu_abort(env,
"Performance counter exception is not implemented yet !\n"); "Performance counter exception is not implemented yet !\n");
@ -3005,13 +3067,16 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
/* Save MSR */ /* Save MSR */
env->spr[srr1] = msr; env->spr[srr1] = msr;
/* If any alternate SRR register are defined, duplicate saved values */ /* If any alternate SRR register are defined, duplicate saved values */
if (asrr0 != -1) if (asrr0 != -1) {
env->spr[asrr0] = env->spr[srr0]; env->spr[asrr0] = env->spr[srr0];
if (asrr1 != -1) }
if (asrr1 != -1) {
env->spr[asrr1] = env->spr[srr1]; env->spr[asrr1] = env->spr[srr1];
}
/* If we disactivated any translation, flush TLBs */ /* If we disactivated any translation, flush TLBs */
if (msr & ((1 << MSR_IR) | (1 << MSR_DR))) if (msr & ((1 << MSR_IR) | (1 << MSR_DR))) {
tlb_flush(env, 1); tlb_flush(env, 1);
}
if (msr_ile) { if (msr_ile) {
new_msr |= (target_ulong)1 << MSR_LE; new_msr |= (target_ulong)1 << MSR_LE;
@ -3193,8 +3258,9 @@ PowerPCCPU *cpu_ppc_init(const char *cpu_model)
const ppc_def_t *def; const ppc_def_t *def;
def = cpu_ppc_find_by_name(cpu_model); def = cpu_ppc_find_by_name(cpu_model);
if (!def) if (!def) {
return NULL; return NULL;
}
cpu = POWERPC_CPU(object_new(TYPE_POWERPC_CPU)); cpu = POWERPC_CPU(object_new(TYPE_POWERPC_CPU));
env = &cpu->env; env = &cpu->env;