PowerPC MMU and exception fixes:
* PowerPC 601 (and probably POWER/POWER2) uses a different BAT format than later PowerPC implementation. * Bugfix in BATs check: must not stop after 4 BATs when more are provided. * Enable POWER 'rac' instruction. * Fix exception prefix for all supported PowerPC implementations. * Fix exceptions, MMU model and bus model for PowerPC 601 & 620. * Enable PowerPC 620 as it could mostly boot a PreP target. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3518 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
f10c315f8f
commit
faadf50e29
|
@ -102,6 +102,8 @@ enum {
|
||||||
POWERPC_MMU_BOOKE,
|
POWERPC_MMU_BOOKE,
|
||||||
/* BookE FSL MMU model */
|
/* BookE FSL MMU model */
|
||||||
POWERPC_MMU_BOOKE_FSL,
|
POWERPC_MMU_BOOKE_FSL,
|
||||||
|
/* PowerPC 601 MMU model (specific BATs format) */
|
||||||
|
POWERPC_MMU_601,
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
/* 64 bits PowerPC MMU */
|
/* 64 bits PowerPC MMU */
|
||||||
POWERPC_MMU_64B,
|
POWERPC_MMU_64B,
|
||||||
|
|
|
@ -98,7 +98,7 @@ void do_raise_exception_err (uint32_t exception, int error_code);
|
||||||
void do_raise_exception (uint32_t exception);
|
void do_raise_exception (uint32_t exception);
|
||||||
|
|
||||||
int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong vaddr,
|
int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong vaddr,
|
||||||
int rw, int access_type, int check_BATs);
|
int rw, int access_type);
|
||||||
|
|
||||||
void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
|
void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
|
||||||
target_ulong pte0, target_ulong pte1);
|
target_ulong pte0, target_ulong pte1);
|
||||||
|
|
|
@ -448,12 +448,65 @@ static always_inline int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform BAT hit & translation */
|
/* Perform BAT hit & translation */
|
||||||
|
static always_inline void bat_size_prot (CPUState *env, target_ulong *blp,
|
||||||
|
int *validp, int *protp,
|
||||||
|
target_ulong *BATu, target_ulong *BATl)
|
||||||
|
{
|
||||||
|
target_ulong bl;
|
||||||
|
int pp, valid, prot;
|
||||||
|
|
||||||
|
bl = (*BATu & 0x00001FFC) << 15;
|
||||||
|
valid = 0;
|
||||||
|
prot = 0;
|
||||||
|
if (((msr_pr == 0) && (*BATu & 0x00000002)) ||
|
||||||
|
((msr_pr != 0) && (*BATu & 0x00000001))) {
|
||||||
|
valid = 1;
|
||||||
|
pp = *BATl & 0x00000003;
|
||||||
|
if (pp != 0) {
|
||||||
|
prot = PAGE_READ | PAGE_EXEC;
|
||||||
|
if (pp == 0x2)
|
||||||
|
prot |= PAGE_WRITE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*blp = bl;
|
||||||
|
*validp = valid;
|
||||||
|
*protp = prot;
|
||||||
|
}
|
||||||
|
|
||||||
|
static always_inline void bat_601_size_prot (CPUState *env,target_ulong *blp,
|
||||||
|
int *validp, int *protp,
|
||||||
|
target_ulong *BATu,
|
||||||
|
target_ulong *BATl)
|
||||||
|
{
|
||||||
|
target_ulong bl;
|
||||||
|
int key, pp, valid, prot;
|
||||||
|
|
||||||
|
bl = (*BATl & 0x0000003F) << 17;
|
||||||
|
if (loglevel != 0) {
|
||||||
|
fprintf(logfile, "b %02x ==> bl %08x msk %08x\n",
|
||||||
|
*BATl & 0x0000003F, bl, ~bl);
|
||||||
|
}
|
||||||
|
prot = 0;
|
||||||
|
valid = (*BATl >> 6) & 1;
|
||||||
|
if (valid) {
|
||||||
|
pp = *BATu & 0x00000003;
|
||||||
|
if (msr_pr == 0)
|
||||||
|
key = (*BATu >> 3) & 1;
|
||||||
|
else
|
||||||
|
key = (*BATu >> 2) & 1;
|
||||||
|
prot = pp_check(key, pp, 0);
|
||||||
|
}
|
||||||
|
*blp = bl;
|
||||||
|
*validp = valid;
|
||||||
|
*protp = prot;
|
||||||
|
}
|
||||||
|
|
||||||
static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
|
static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
|
||||||
target_ulong virtual, 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 base, BEPIl, BEPIu, bl;
|
target_ulong base, BEPIl, BEPIu, bl;
|
||||||
int i, pp, pr;
|
int i, valid, prot;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
#if defined (DEBUG_BATS)
|
#if defined (DEBUG_BATS)
|
||||||
|
@ -462,7 +515,6 @@ static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
|
||||||
type == ACCESS_CODE ? 'I' : 'D', virtual);
|
type == ACCESS_CODE ? 'I' : 'D', virtual);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
pr = msr_pr;
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ACCESS_CODE:
|
case ACCESS_CODE:
|
||||||
BATlt = env->IBAT[1];
|
BATlt = env->IBAT[1];
|
||||||
|
@ -480,12 +532,16 @@ static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
base = virtual & 0xFFFC0000;
|
base = virtual & 0xFFFC0000;
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < env->nb_BATs; i++) {
|
||||||
BATu = &BATut[i];
|
BATu = &BATut[i];
|
||||||
BATl = &BATlt[i];
|
BATl = &BATlt[i];
|
||||||
BEPIu = *BATu & 0xF0000000;
|
BEPIu = *BATu & 0xF0000000;
|
||||||
BEPIl = *BATu & 0x0FFE0000;
|
BEPIl = *BATu & 0x0FFE0000;
|
||||||
bl = (*BATu & 0x00001FFC) << 15;
|
if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
|
||||||
|
bat_601_size_prot(env, &bl, &valid, &prot, BATu, BATl);
|
||||||
|
} else {
|
||||||
|
bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
|
||||||
|
}
|
||||||
#if defined (DEBUG_BATS)
|
#if defined (DEBUG_BATS)
|
||||||
if (loglevel != 0) {
|
if (loglevel != 0) {
|
||||||
fprintf(logfile, "%s: %cBAT%d v 0x" ADDRX " BATu 0x" ADDRX
|
fprintf(logfile, "%s: %cBAT%d v 0x" ADDRX " BATu 0x" ADDRX
|
||||||
|
@ -497,20 +553,13 @@ static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
|
||||||
if ((virtual & 0xF0000000) == BEPIu &&
|
if ((virtual & 0xF0000000) == BEPIu &&
|
||||||
((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
|
((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
|
||||||
/* BAT matches */
|
/* BAT matches */
|
||||||
if (((pr == 0) && (*BATu & 0x00000002)) ||
|
if (valid != 0) {
|
||||||
((pr != 0) && (*BATu & 0x00000001))) {
|
|
||||||
/* Get physical address */
|
/* Get physical address */
|
||||||
ctx->raddr = (*BATl & 0xF0000000) |
|
ctx->raddr = (*BATl & 0xF0000000) |
|
||||||
((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
|
((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
|
||||||
(virtual & 0x0001F000);
|
(virtual & 0x0001F000);
|
||||||
/* Compute access rights */
|
/* Compute access rights */
|
||||||
pp = *BATl & 0x00000003;
|
ctx->prot = prot;
|
||||||
ctx->prot = 0;
|
|
||||||
if (pp != 0) {
|
|
||||||
ctx->prot = PAGE_READ | PAGE_EXEC;
|
|
||||||
if (pp == 0x2)
|
|
||||||
ctx->prot |= PAGE_WRITE;
|
|
||||||
}
|
|
||||||
ret = check_prot(ctx->prot, rw, type);
|
ret = check_prot(ctx->prot, rw, type);
|
||||||
#if defined (DEBUG_BATS)
|
#if defined (DEBUG_BATS)
|
||||||
if (ret == 0 && loglevel != 0) {
|
if (ret == 0 && loglevel != 0) {
|
||||||
|
@ -1302,6 +1351,7 @@ static always_inline int check_physical (CPUState *env, mmu_ctx_t *ctx,
|
||||||
ret = 0;
|
ret = 0;
|
||||||
switch (env->mmu_model) {
|
switch (env->mmu_model) {
|
||||||
case POWERPC_MMU_32B:
|
case POWERPC_MMU_32B:
|
||||||
|
case POWERPC_MMU_601:
|
||||||
case POWERPC_MMU_SOFT_6xx:
|
case POWERPC_MMU_SOFT_6xx:
|
||||||
case POWERPC_MMU_SOFT_74xx:
|
case POWERPC_MMU_SOFT_74xx:
|
||||||
case POWERPC_MMU_SOFT_4xx:
|
case POWERPC_MMU_SOFT_4xx:
|
||||||
|
@ -1353,7 +1403,7 @@ static always_inline int check_physical (CPUState *env, mmu_ctx_t *ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
|
int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
|
||||||
int rw, int access_type, int check_BATs)
|
int rw, int access_type)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -1370,15 +1420,15 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
|
||||||
ret = -1;
|
ret = -1;
|
||||||
switch (env->mmu_model) {
|
switch (env->mmu_model) {
|
||||||
case POWERPC_MMU_32B:
|
case POWERPC_MMU_32B:
|
||||||
|
case POWERPC_MMU_601:
|
||||||
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 */
|
|
||||||
if (check_BATs)
|
|
||||||
ret = get_bat(env, ctx, eaddr, rw, access_type);
|
|
||||||
/* No break here */
|
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
case POWERPC_MMU_64B:
|
case POWERPC_MMU_64B:
|
||||||
#endif
|
#endif
|
||||||
|
/* Try to find a BAT */
|
||||||
|
if (env->nb_BATs != 0)
|
||||||
|
ret = get_bat(env, ctx, eaddr, rw, access_type);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* We didn't match any BAT entry or don't have BATs */
|
/* We didn't match any BAT entry or don't have BATs */
|
||||||
ret = get_segment(env, ctx, eaddr, rw, access_type);
|
ret = get_segment(env, ctx, eaddr, rw, access_type);
|
||||||
|
@ -1419,7 +1469,7 @@ target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
|
||||||
{
|
{
|
||||||
mmu_ctx_t ctx;
|
mmu_ctx_t ctx;
|
||||||
|
|
||||||
if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT, 1) != 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;
|
||||||
|
@ -1444,7 +1494,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
||||||
access_type = ACCESS_INT;
|
access_type = ACCESS_INT;
|
||||||
// access_type = env->access_type;
|
// access_type = env->access_type;
|
||||||
}
|
}
|
||||||
ret = get_physical_address(env, &ctx, address, rw, access_type, 1);
|
ret = get_physical_address(env, &ctx, address, rw, access_type);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = tlb_set_page_exec(env, address & TARGET_PAGE_MASK,
|
ret = tlb_set_page_exec(env, address & TARGET_PAGE_MASK,
|
||||||
ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
|
ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
|
||||||
|
@ -1476,6 +1526,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
||||||
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:
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
case POWERPC_MMU_64B:
|
case POWERPC_MMU_64B:
|
||||||
#endif
|
#endif
|
||||||
|
@ -1567,6 +1618,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
||||||
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:
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
case POWERPC_MMU_64B:
|
case POWERPC_MMU_64B:
|
||||||
#endif
|
#endif
|
||||||
|
@ -1809,6 +1861,7 @@ void ppc_tlb_invalidate_all (CPUPPCState *env)
|
||||||
cpu_abort(env, "MMU model not implemented\n");
|
cpu_abort(env, "MMU model not implemented\n");
|
||||||
break;
|
break;
|
||||||
case POWERPC_MMU_32B:
|
case POWERPC_MMU_32B:
|
||||||
|
case POWERPC_MMU_601:
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
case POWERPC_MMU_64B:
|
case POWERPC_MMU_64B:
|
||||||
#endif /* defined(TARGET_PPC64) */
|
#endif /* defined(TARGET_PPC64) */
|
||||||
|
@ -1848,6 +1901,7 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
|
||||||
cpu_abort(env, "MMU model not implemented\n");
|
cpu_abort(env, "MMU model not implemented\n");
|
||||||
break;
|
break;
|
||||||
case POWERPC_MMU_32B:
|
case POWERPC_MMU_32B:
|
||||||
|
case POWERPC_MMU_601:
|
||||||
/* tlbie invalidate TLBs for all segments */
|
/* tlbie invalidate TLBs for all segments */
|
||||||
addr &= ~((target_ulong)-1 << 28);
|
addr &= ~((target_ulong)-1 << 28);
|
||||||
/* XXX: this case should be optimized,
|
/* XXX: this case should be optimized,
|
||||||
|
|
|
@ -1682,15 +1682,18 @@ void do_POWER_mulo (void)
|
||||||
#if !defined (CONFIG_USER_ONLY)
|
#if !defined (CONFIG_USER_ONLY)
|
||||||
void do_POWER_rac (void)
|
void do_POWER_rac (void)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
mmu_ctx_t ctx;
|
mmu_ctx_t ctx;
|
||||||
|
int nb_BATs;
|
||||||
|
|
||||||
/* We don't have to generate many instances of this instruction,
|
/* We don't have to generate many instances of this instruction,
|
||||||
* as rac is supervisor only.
|
* as rac is supervisor only.
|
||||||
*/
|
*/
|
||||||
if (get_physical_address(env, &ctx, T0, 0, ACCESS_INT, 1) == 0)
|
/* XXX: FIX THIS: Pretend we have no BAT */
|
||||||
|
nb_BATs = env->nb_BATs;
|
||||||
|
env->nb_BATs = 0;
|
||||||
|
if (get_physical_address(env, &ctx, T0, 0, ACCESS_INT) == 0)
|
||||||
T0 = ctx.raddr;
|
T0 = ctx.raddr;
|
||||||
#endif
|
env->nb_BATs = nb_BATs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_POWER_rfsvc (void)
|
void do_POWER_rfsvc (void)
|
||||||
|
|
|
@ -2246,9 +2246,9 @@ static void init_excp_4xx_real (CPUPPCState *env)
|
||||||
env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
|
env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
|
||||||
env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
|
env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
|
||||||
env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
|
env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
|
||||||
env->excp_prefix = 0x00000000;
|
env->excp_prefix = 0x00000000UL;
|
||||||
env->ivor_mask = 0x0000FFF0;
|
env->ivor_mask = 0x0000FFF0UL;
|
||||||
env->ivpr_mask = 0xFFFF0000;
|
env->ivpr_mask = 0xFFFF0000UL;
|
||||||
/* Hardware reset vector */
|
/* Hardware reset vector */
|
||||||
env->hreset_vector = 0xFFFFFFFCUL;
|
env->hreset_vector = 0xFFFFFFFCUL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2271,9 +2271,9 @@ static void init_excp_4xx_softmmu (CPUPPCState *env)
|
||||||
env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100;
|
env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100;
|
||||||
env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200;
|
env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200;
|
||||||
env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
|
env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
|
||||||
env->excp_prefix = 0x00000000;
|
env->excp_prefix = 0x00000000UL;
|
||||||
env->ivor_mask = 0x0000FFF0;
|
env->ivor_mask = 0x0000FFF0UL;
|
||||||
env->ivpr_mask = 0xFFFF0000;
|
env->ivpr_mask = 0xFFFF0000UL;
|
||||||
/* Hardware reset vector */
|
/* Hardware reset vector */
|
||||||
env->hreset_vector = 0xFFFFFFFCUL;
|
env->hreset_vector = 0xFFFFFFFCUL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2298,9 +2298,9 @@ static void init_excp_BookE (CPUPPCState *env)
|
||||||
env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000;
|
env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000;
|
||||||
env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000;
|
env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000;
|
||||||
env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000;
|
env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000;
|
||||||
env->excp_prefix = 0x00000000;
|
env->excp_prefix = 0x00000000UL;
|
||||||
env->ivor_mask = 0x0000FFE0;
|
env->ivor_mask = 0x0000FFE0UL;
|
||||||
env->ivpr_mask = 0xFFFF0000;
|
env->ivpr_mask = 0xFFFF0000UL;
|
||||||
/* Hardware reset vector */
|
/* Hardware reset vector */
|
||||||
env->hreset_vector = 0xFFFFFFFCUL;
|
env->hreset_vector = 0xFFFFFFFCUL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2321,7 +2321,7 @@ static void init_excp_601 (CPUPPCState *env)
|
||||||
env->excp_vectors[POWERPC_EXCP_IO] = 0x00000A00;
|
env->excp_vectors[POWERPC_EXCP_IO] = 0x00000A00;
|
||||||
env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
|
env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
|
||||||
env->excp_vectors[POWERPC_EXCP_RUNM] = 0x00002000;
|
env->excp_vectors[POWERPC_EXCP_RUNM] = 0x00002000;
|
||||||
env->excp_prefix = 0xFFF00000;
|
env->excp_prefix = 0xFFF00000UL;
|
||||||
/* Hardware reset vector */
|
/* Hardware reset vector */
|
||||||
env->hreset_vector = 0x00000100UL;
|
env->hreset_vector = 0x00000100UL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2349,7 +2349,7 @@ static void init_excp_602 (CPUPPCState *env)
|
||||||
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
||||||
env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001500;
|
env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001500;
|
||||||
env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001600;
|
env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001600;
|
||||||
env->excp_prefix = 0xFFF00000;
|
env->excp_prefix = 0xFFF00000UL;
|
||||||
/* Hardware reset vector */
|
/* Hardware reset vector */
|
||||||
env->hreset_vector = 0xFFFFFFFCUL;
|
env->hreset_vector = 0xFFFFFFFCUL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2374,6 +2374,7 @@ static void init_excp_603 (CPUPPCState *env)
|
||||||
env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
|
env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
|
||||||
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
|
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
|
||||||
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
||||||
|
env->excp_prefix = 0x00000000UL;
|
||||||
/* Hardware reset vector */
|
/* Hardware reset vector */
|
||||||
env->hreset_vector = 0xFFFFFFFCUL;
|
env->hreset_vector = 0xFFFFFFFCUL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2399,6 +2400,7 @@ static void init_excp_G2 (CPUPPCState *env)
|
||||||
env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
|
env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
|
||||||
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
|
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
|
||||||
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
||||||
|
env->excp_prefix = 0x00000000UL;
|
||||||
/* Hardware reset vector */
|
/* Hardware reset vector */
|
||||||
env->hreset_vector = 0xFFFFFFFCUL;
|
env->hreset_vector = 0xFFFFFFFCUL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2421,6 +2423,7 @@ static void init_excp_604 (CPUPPCState *env)
|
||||||
env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
|
env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
|
||||||
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
|
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
|
||||||
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
||||||
|
env->excp_prefix = 0x00000000UL;
|
||||||
/* Hardware reset vector */
|
/* Hardware reset vector */
|
||||||
env->hreset_vector = 0xFFFFFFFCUL;
|
env->hreset_vector = 0xFFFFFFFCUL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2433,7 +2436,9 @@ static void init_excp_620 (CPUPPCState *env)
|
||||||
env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
|
env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
|
||||||
env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
|
env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
|
||||||
env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
|
env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
|
||||||
|
env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380;
|
||||||
env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
|
env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
|
||||||
|
env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480;
|
||||||
env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
|
env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
|
||||||
env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
|
env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
|
||||||
env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
|
env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
|
||||||
|
@ -2445,8 +2450,9 @@ static void init_excp_620 (CPUPPCState *env)
|
||||||
env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
|
env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
|
||||||
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
|
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
|
||||||
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
||||||
|
env->excp_prefix = 0xFFF00000UL;
|
||||||
/* Hardware reset vector */
|
/* Hardware reset vector */
|
||||||
env->hreset_vector = 0x0000000000000100ULL; /* ? */
|
env->hreset_vector = 0x0000000000000100ULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* defined(TARGET_PPC64) */
|
#endif /* defined(TARGET_PPC64) */
|
||||||
|
@ -2468,6 +2474,7 @@ static void init_excp_7x0 (CPUPPCState *env)
|
||||||
env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
|
env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
|
||||||
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
|
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
|
||||||
env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
|
env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
|
||||||
|
env->excp_prefix = 0x00000000UL;
|
||||||
/* Hardware reset vector */
|
/* Hardware reset vector */
|
||||||
env->hreset_vector = 0xFFFFFFFCUL;
|
env->hreset_vector = 0xFFFFFFFCUL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2491,6 +2498,7 @@ static void init_excp_750FX (CPUPPCState *env)
|
||||||
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
|
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
|
||||||
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
||||||
env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
|
env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
|
||||||
|
env->excp_prefix = 0x00000000UL;
|
||||||
/* Hardware reset vector */
|
/* Hardware reset vector */
|
||||||
env->hreset_vector = 0xFFFFFFFCUL;
|
env->hreset_vector = 0xFFFFFFFCUL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2517,6 +2525,7 @@ static void init_excp_7x5 (CPUPPCState *env)
|
||||||
env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
|
env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
|
||||||
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
|
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
|
||||||
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
||||||
|
env->excp_prefix = 0x00000000UL;
|
||||||
/* Hardware reset vector */
|
/* Hardware reset vector */
|
||||||
env->hreset_vector = 0xFFFFFFFCUL;
|
env->hreset_vector = 0xFFFFFFFCUL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2542,6 +2551,7 @@ static void init_excp_7400 (CPUPPCState *env)
|
||||||
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
||||||
env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
|
env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
|
||||||
env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
|
env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
|
||||||
|
env->excp_prefix = 0x00000000UL;
|
||||||
/* Hardware reset vector */
|
/* Hardware reset vector */
|
||||||
env->hreset_vector = 0xFFFFFFFCUL;
|
env->hreset_vector = 0xFFFFFFFCUL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2569,6 +2579,7 @@ static void init_excp_7450 (CPUPPCState *env)
|
||||||
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
|
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
|
||||||
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
|
||||||
env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
|
env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
|
||||||
|
env->excp_prefix = 0x00000000UL;
|
||||||
/* Hardware reset vector */
|
/* Hardware reset vector */
|
||||||
env->hreset_vector = 0xFFFFFFFCUL;
|
env->hreset_vector = 0xFFFFFFFCUL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2600,6 +2611,7 @@ static void init_excp_970 (CPUPPCState *env)
|
||||||
env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600;
|
env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600;
|
||||||
env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700;
|
env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700;
|
||||||
env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800;
|
env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800;
|
||||||
|
env->excp_prefix = 0x00000000FFF00000ULL;
|
||||||
/* Hardware reset vector */
|
/* Hardware reset vector */
|
||||||
env->hreset_vector = 0x0000000000000100ULL;
|
env->hreset_vector = 0x0000000000000100ULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -3232,7 +3244,7 @@ static void init_proc_e500 (CPUPPCState *env)
|
||||||
#define POWERPC_INSNS_601 (POWERPC_INSNS_6xx | PPC_CACHE_DCBZ | \
|
#define POWERPC_INSNS_601 (POWERPC_INSNS_6xx | PPC_CACHE_DCBZ | \
|
||||||
PPC_SEGMENT | PPC_EXTERN | PPC_POWER_BR)
|
PPC_SEGMENT | PPC_EXTERN | PPC_POWER_BR)
|
||||||
#define POWERPC_MSRM_601 (0x000000000000FD70ULL)
|
#define POWERPC_MSRM_601 (0x000000000000FD70ULL)
|
||||||
#define POWERPC_MMU_601 (POWERPC_MMU_32B)
|
//#define POWERPC_MMU_601 (POWERPC_MMU_601)
|
||||||
//#define POWERPC_EXCP_601 (POWERPC_EXCP_601)
|
//#define POWERPC_EXCP_601 (POWERPC_EXCP_601)
|
||||||
#define POWERPC_INPUT_601 (PPC_FLAGS_INPUT_6xx)
|
#define POWERPC_INPUT_601 (PPC_FLAGS_INPUT_6xx)
|
||||||
#define POWERPC_BFDM_601 (bfd_mach_ppc_601)
|
#define POWERPC_BFDM_601 (bfd_mach_ppc_601)
|
||||||
|
@ -3248,7 +3260,7 @@ static void init_proc_601 (CPUPPCState *env)
|
||||||
spr_register(env, SPR_HID0, "HID0",
|
spr_register(env, SPR_HID0, "HID0",
|
||||||
SPR_NOACCESS, SPR_NOACCESS,
|
SPR_NOACCESS, SPR_NOACCESS,
|
||||||
&spr_read_generic, &spr_write_generic,
|
&spr_read_generic, &spr_write_generic,
|
||||||
0x00000000);
|
0x80010080);
|
||||||
/* XXX : not implemented */
|
/* XXX : not implemented */
|
||||||
spr_register(env, SPR_HID1, "HID1",
|
spr_register(env, SPR_HID1, "HID1",
|
||||||
SPR_NOACCESS, SPR_NOACCESS,
|
SPR_NOACCESS, SPR_NOACCESS,
|
||||||
|
@ -3278,7 +3290,8 @@ static void init_proc_601 (CPUPPCState *env)
|
||||||
init_excp_601(env);
|
init_excp_601(env);
|
||||||
env->dcache_line_size = 64;
|
env->dcache_line_size = 64;
|
||||||
env->icache_line_size = 64;
|
env->icache_line_size = 64;
|
||||||
/* XXX: TODO: allocate internal IRQ controller */
|
/* Allocate hardware IRQ controller */
|
||||||
|
ppc6xx_irq_init(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PowerPC 602 */
|
/* PowerPC 602 */
|
||||||
|
@ -4182,9 +4195,6 @@ static void init_proc_970 (CPUPPCState *env)
|
||||||
SPR_NOACCESS, SPR_NOACCESS,
|
SPR_NOACCESS, SPR_NOACCESS,
|
||||||
&spr_read_generic, &spr_write_generic,
|
&spr_read_generic, &spr_write_generic,
|
||||||
0xFFF00000); /* XXX: This is a hack */
|
0xFFF00000); /* XXX: This is a hack */
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
|
||||||
env->excp_prefix = 0xFFF00000;
|
|
||||||
#endif
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
env->slb_nr = 32;
|
env->slb_nr = 32;
|
||||||
#endif
|
#endif
|
||||||
|
@ -4259,9 +4269,6 @@ static void init_proc_970FX (CPUPPCState *env)
|
||||||
SPR_NOACCESS, SPR_NOACCESS,
|
SPR_NOACCESS, SPR_NOACCESS,
|
||||||
&spr_read_generic, &spr_write_generic,
|
&spr_read_generic, &spr_write_generic,
|
||||||
0xFFF00000); /* XXX: This is a hack */
|
0xFFF00000); /* XXX: This is a hack */
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
|
||||||
env->excp_prefix = 0xFFF00000;
|
|
||||||
#endif
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
env->slb_nr = 32;
|
env->slb_nr = 32;
|
||||||
#endif
|
#endif
|
||||||
|
@ -4336,9 +4343,6 @@ static void init_proc_970GX (CPUPPCState *env)
|
||||||
SPR_NOACCESS, SPR_NOACCESS,
|
SPR_NOACCESS, SPR_NOACCESS,
|
||||||
&spr_read_generic, &spr_write_generic,
|
&spr_read_generic, &spr_write_generic,
|
||||||
0xFFF00000); /* XXX: This is a hack */
|
0xFFF00000); /* XXX: This is a hack */
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
|
||||||
env->excp_prefix = 0xFFF00000;
|
|
||||||
#endif
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
env->slb_nr = 32;
|
env->slb_nr = 32;
|
||||||
#endif
|
#endif
|
||||||
|
@ -4413,9 +4417,6 @@ static void init_proc_970MP (CPUPPCState *env)
|
||||||
SPR_NOACCESS, SPR_NOACCESS,
|
SPR_NOACCESS, SPR_NOACCESS,
|
||||||
&spr_read_generic, &spr_write_generic,
|
&spr_read_generic, &spr_write_generic,
|
||||||
0xFFF00000); /* XXX: This is a hack */
|
0xFFF00000); /* XXX: This is a hack */
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
|
||||||
env->excp_prefix = 0xFFF00000;
|
|
||||||
#endif
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
env->slb_nr = 32;
|
env->slb_nr = 32;
|
||||||
#endif
|
#endif
|
||||||
|
@ -4432,7 +4433,7 @@ static void init_proc_970MP (CPUPPCState *env)
|
||||||
#define POWERPC_MSRM_620 (0x800000000005FF73ULL)
|
#define POWERPC_MSRM_620 (0x800000000005FF73ULL)
|
||||||
#define POWERPC_MMU_620 (POWERPC_MMU_64B)
|
#define POWERPC_MMU_620 (POWERPC_MMU_64B)
|
||||||
#define POWERPC_EXCP_620 (POWERPC_EXCP_970)
|
#define POWERPC_EXCP_620 (POWERPC_EXCP_970)
|
||||||
#define POWERPC_INPUT_620 (PPC_FLAGS_INPUT_970)
|
#define POWERPC_INPUT_620 (PPC_FLAGS_INPUT_6xx)
|
||||||
#define POWERPC_BFDM_620 (bfd_mach_ppc64)
|
#define POWERPC_BFDM_620 (bfd_mach_ppc64)
|
||||||
#define POWERPC_FLAG_620 (POWERPC_FLAG_SE | POWERPC_FLAG_BE)
|
#define POWERPC_FLAG_620 (POWERPC_FLAG_SE | POWERPC_FLAG_BE)
|
||||||
#define check_pow_620 check_pow_nocheck /* Check this */
|
#define check_pow_620 check_pow_nocheck /* Check this */
|
||||||
|
@ -4456,7 +4457,8 @@ static void init_proc_620 (CPUPPCState *env)
|
||||||
init_excp_620(env);
|
init_excp_620(env);
|
||||||
env->dcache_line_size = 64;
|
env->dcache_line_size = 64;
|
||||||
env->icache_line_size = 64;
|
env->icache_line_size = 64;
|
||||||
/* XXX: TODO: initialize internal interrupt controller */
|
/* Allocate hardware IRQ controller */
|
||||||
|
ppc6xx_irq_init(env);
|
||||||
}
|
}
|
||||||
#endif /* defined (TARGET_PPC64) */
|
#endif /* defined (TARGET_PPC64) */
|
||||||
|
|
||||||
|
@ -5771,10 +5773,8 @@ static ppc_def_t ppc_defs[] = {
|
||||||
POWERPC_DEF("7457v1.2", CPU_POWERPC_74x7_v12, 0xFFFFFFFF, 7455),
|
POWERPC_DEF("7457v1.2", CPU_POWERPC_74x7_v12, 0xFFFFFFFF, 7455),
|
||||||
/* 64 bits PowerPC */
|
/* 64 bits PowerPC */
|
||||||
#if defined (TARGET_PPC64)
|
#if defined (TARGET_PPC64)
|
||||||
#if defined (TODO)
|
|
||||||
/* PowerPC 620 */
|
/* PowerPC 620 */
|
||||||
POWERPC_DEF("620", CPU_POWERPC_620, 0xFFFFFFFF, 620),
|
POWERPC_DEF("620", CPU_POWERPC_620, 0xFFFFFFFF, 620),
|
||||||
#endif
|
|
||||||
#if defined (TODO)
|
#if defined (TODO)
|
||||||
/* PowerPC 630 (POWER3) */
|
/* PowerPC 630 (POWER3) */
|
||||||
POWERPC_DEF("630", CPU_POWERPC_630, 0xFFFFFFFF, 630),
|
POWERPC_DEF("630", CPU_POWERPC_630, 0xFFFFFFFF, 630),
|
||||||
|
|
Loading…
Reference in a new issue