Revision 576c2cdc

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