Revision 576c2cdc target-sparc/op_helper.c
b/target-sparc/op_helper.c | ||
---|---|---|
3714 | 3714 |
int is_asi, int size) |
3715 | 3715 |
{ |
3716 | 3716 |
CPUState *saved_env; |
3717 |
int fault_type; |
|
3717 | 3718 |
|
3718 | 3719 |
/* XXX: hack to restore env in all cases, even if not called from |
3719 | 3720 |
generated code */ |
... | ... | |
3731 | 3732 |
is_exec ? "exec" : is_write ? "write" : "read", size, |
3732 | 3733 |
size == 1 ? "" : "s", addr, env->pc); |
3733 | 3734 |
#endif |
3734 |
if (env->mmuregs[3]) /* Fault status register */ |
|
3735 |
env->mmuregs[3] = 1; /* overflow (not read before another fault) */ |
|
3736 |
if (is_asi) |
|
3737 |
env->mmuregs[3] |= 1 << 16; |
|
3738 |
if (env->psrs) |
|
3739 |
env->mmuregs[3] |= 1 << 5; |
|
3740 |
if (is_exec) |
|
3741 |
env->mmuregs[3] |= 1 << 6; |
|
3742 |
if (is_write) |
|
3743 |
env->mmuregs[3] |= 1 << 7; |
|
3744 |
env->mmuregs[3] |= (5 << 2) | 2; |
|
3745 |
env->mmuregs[4] = addr; /* Fault address register */ |
|
3735 |
/* Don't overwrite translation and access faults */ |
|
3736 |
fault_type = (env->mmuregs[3] & 0x1c) >> 2; |
|
3737 |
if ((fault_type > 4) || (fault_type == 0)) { |
|
3738 |
env->mmuregs[3] = 0; /* Fault status register */ |
|
3739 |
if (is_asi) |
|
3740 |
env->mmuregs[3] |= 1 << 16; |
|
3741 |
if (env->psrs) |
|
3742 |
env->mmuregs[3] |= 1 << 5; |
|
3743 |
if (is_exec) |
|
3744 |
env->mmuregs[3] |= 1 << 6; |
|
3745 |
if (is_write) |
|
3746 |
env->mmuregs[3] |= 1 << 7; |
|
3747 |
env->mmuregs[3] |= (5 << 2) | 2; |
|
3748 |
/* SuperSPARC will never place instruction fault addresses in the FAR */ |
|
3749 |
if (!is_exec) { |
|
3750 |
env->mmuregs[4] = addr; /* Fault address register */ |
|
3751 |
} |
|
3752 |
} |
|
3753 |
/* overflow (same type fault was not read before another fault) */ |
|
3754 |
if (fault_type == ((env->mmuregs[3] & 0x1c)) >> 2) { |
|
3755 |
env->mmuregs[3] |= 1; |
|
3756 |
} |
|
3757 |
|
|
3746 | 3758 |
if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) { |
3747 | 3759 |
if (is_exec) |
3748 | 3760 |
raise_exception(TT_CODE_ACCESS); |
... | ... | |
3750 | 3762 |
raise_exception(TT_DATA_ACCESS); |
3751 | 3763 |
} |
3752 | 3764 |
env = saved_env; |
3765 |
|
|
3766 |
/* flush neverland mappings created during no-fault mode, |
|
3767 |
so the sequential MMU faults report proper fault types */ |
|
3768 |
if (env->mmuregs[0] & MMU_NF) { |
|
3769 |
tlb_flush(env, 1); |
|
3770 |
} |
|
3753 | 3771 |
} |
3754 | 3772 |
#else |
3755 | 3773 |
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, |
Also available in: Unified diff