Revision 91736d37 target-sparc/op_helper.c

b/target-sparc/op_helper.c
68 68
    }
69 69
}
70 70

  
71
static inline void set_cwp(int new_cwp)
72
{
73
    cpu_set_cwp(env, new_cwp);
74
}
75

  
71 76
void helper_check_align(target_ulong addr, uint32_t align)
72 77
{
73 78
    if (addr & align) {
......
2668 2673
    }
2669 2674
}
2670 2675

  
2671
void change_pstate(uint64_t new_pstate)
2676
static inline void change_pstate(uint64_t new_pstate)
2672 2677
{
2673 2678
    uint64_t pstate_regs, new_pstate_regs;
2674 2679
    uint64_t *src, *dst;
......
2716 2721
}
2717 2722
#endif
2718 2723

  
2719
void cpu_set_cwp(CPUState *env1, int new_cwp)
2724
void helper_flush(target_ulong addr)
2720 2725
{
2721
    /* put the modified wrap registers at their proper location */
2722
    if (env1->cwp == env1->nwindows - 1)
2723
        memcpy32(env1->regbase, env1->regbase + env1->nwindows * 16);
2724
    env1->cwp = new_cwp;
2725
    /* put the wrap registers at their temporary location */
2726
    if (new_cwp == env1->nwindows - 1)
2727
        memcpy32(env1->regbase + env1->nwindows * 16, env1->regbase);
2728
    env1->regwptr = env1->regbase + (new_cwp * 16);
2726
    addr &= ~7;
2727
    tb_invalidate_page_range(addr, addr + 8);
2729 2728
}
2730 2729

  
2731
void set_cwp(int new_cwp)
2732
{
2733
    cpu_set_cwp(env, new_cwp);
2730
#ifdef TARGET_SPARC64
2731
#ifdef DEBUG_PCALL
2732
static const char * const excp_names[0x80] = {
2733
    [TT_TFAULT] = "Instruction Access Fault",
2734
    [TT_TMISS] = "Instruction Access MMU Miss",
2735
    [TT_CODE_ACCESS] = "Instruction Access Error",
2736
    [TT_ILL_INSN] = "Illegal Instruction",
2737
    [TT_PRIV_INSN] = "Privileged Instruction",
2738
    [TT_NFPU_INSN] = "FPU Disabled",
2739
    [TT_FP_EXCP] = "FPU Exception",
2740
    [TT_TOVF] = "Tag Overflow",
2741
    [TT_CLRWIN] = "Clean Windows",
2742
    [TT_DIV_ZERO] = "Division By Zero",
2743
    [TT_DFAULT] = "Data Access Fault",
2744
    [TT_DMISS] = "Data Access MMU Miss",
2745
    [TT_DATA_ACCESS] = "Data Access Error",
2746
    [TT_DPROT] = "Data Protection Error",
2747
    [TT_UNALIGNED] = "Unaligned Memory Access",
2748
    [TT_PRIV_ACT] = "Privileged Action",
2749
    [TT_EXTINT | 0x1] = "External Interrupt 1",
2750
    [TT_EXTINT | 0x2] = "External Interrupt 2",
2751
    [TT_EXTINT | 0x3] = "External Interrupt 3",
2752
    [TT_EXTINT | 0x4] = "External Interrupt 4",
2753
    [TT_EXTINT | 0x5] = "External Interrupt 5",
2754
    [TT_EXTINT | 0x6] = "External Interrupt 6",
2755
    [TT_EXTINT | 0x7] = "External Interrupt 7",
2756
    [TT_EXTINT | 0x8] = "External Interrupt 8",
2757
    [TT_EXTINT | 0x9] = "External Interrupt 9",
2758
    [TT_EXTINT | 0xa] = "External Interrupt 10",
2759
    [TT_EXTINT | 0xb] = "External Interrupt 11",
2760
    [TT_EXTINT | 0xc] = "External Interrupt 12",
2761
    [TT_EXTINT | 0xd] = "External Interrupt 13",
2762
    [TT_EXTINT | 0xe] = "External Interrupt 14",
2763
    [TT_EXTINT | 0xf] = "External Interrupt 15",
2764
};
2765
#endif
2766

  
2767
void do_interrupt(CPUState *env)
2768
{
2769
    int intno = env->exception_index;
2770

  
2771
#ifdef DEBUG_PCALL
2772
    if (loglevel & CPU_LOG_INT) {
2773
        static int count;
2774
        const char *name;
2775

  
2776
        if (intno < 0 || intno >= 0x180)
2777
            name = "Unknown";
2778
        else if (intno >= 0x100)
2779
            name = "Trap Instruction";
2780
        else if (intno >= 0xc0)
2781
            name = "Window Fill";
2782
        else if (intno >= 0x80)
2783
            name = "Window Spill";
2784
        else {
2785
            name = excp_names[intno];
2786
            if (!name)
2787
                name = "Unknown";
2788
        }
2789

  
2790
        fprintf(logfile, "%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
2791
                " SP=%016" PRIx64 "\n",
2792
                count, name, intno,
2793
                env->pc,
2794
                env->npc, env->regwptr[6]);
2795
        cpu_dump_state(env, logfile, fprintf, 0);
2796
#if 0
2797
        {
2798
            int i;
2799
            uint8_t *ptr;
2800

  
2801
            fprintf(logfile, "       code=");
2802
            ptr = (uint8_t *)env->pc;
2803
            for(i = 0; i < 16; i++) {
2804
                fprintf(logfile, " %02x", ldub(ptr + i));
2805
            }
2806
            fprintf(logfile, "\n");
2807
        }
2808
#endif
2809
        count++;
2810
    }
2811
#endif
2812
#if !defined(CONFIG_USER_ONLY)
2813
    if (env->tl >= env->maxtl) {
2814
        cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
2815
                  " Error state", env->exception_index, env->tl, env->maxtl);
2816
        return;
2817
    }
2818
#endif
2819
    if (env->tl < env->maxtl - 1) {
2820
        env->tl++;
2821
    } else {
2822
        env->pstate |= PS_RED;
2823
        if (env->tl < env->maxtl)
2824
            env->tl++;
2825
    }
2826
    env->tsptr = &env->ts[env->tl & MAXTL_MASK];
2827
    env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
2828
        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
2829
        GET_CWP64(env);
2830
    env->tsptr->tpc = env->pc;
2831
    env->tsptr->tnpc = env->npc;
2832
    env->tsptr->tt = intno;
2833
    if (!(env->def->features & CPU_FEATURE_GL)) {
2834
        switch (intno) {
2835
        case TT_IVEC:
2836
            change_pstate(PS_PEF | PS_PRIV | PS_IG);
2837
            break;
2838
        case TT_TFAULT:
2839
        case TT_TMISS:
2840
        case TT_DFAULT:
2841
        case TT_DMISS:
2842
        case TT_DPROT:
2843
            change_pstate(PS_PEF | PS_PRIV | PS_MG);
2844
            break;
2845
        default:
2846
            change_pstate(PS_PEF | PS_PRIV | PS_AG);
2847
            break;
2848
        }
2849
    }
2850
    if (intno == TT_CLRWIN)
2851
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
2852
    else if ((intno & 0x1c0) == TT_SPILL)
2853
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
2854
    else if ((intno & 0x1c0) == TT_FILL)
2855
        cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
2856
    env->tbr &= ~0x7fffULL;
2857
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
2858
    env->pc = env->tbr;
2859
    env->npc = env->pc + 4;
2860
    env->exception_index = 0;
2734 2861
}
2862
#else
2863
#ifdef DEBUG_PCALL
2864
static const char * const excp_names[0x80] = {
2865
    [TT_TFAULT] = "Instruction Access Fault",
2866
    [TT_ILL_INSN] = "Illegal Instruction",
2867
    [TT_PRIV_INSN] = "Privileged Instruction",
2868
    [TT_NFPU_INSN] = "FPU Disabled",
2869
    [TT_WIN_OVF] = "Window Overflow",
2870
    [TT_WIN_UNF] = "Window Underflow",
2871
    [TT_UNALIGNED] = "Unaligned Memory Access",
2872
    [TT_FP_EXCP] = "FPU Exception",
2873
    [TT_DFAULT] = "Data Access Fault",
2874
    [TT_TOVF] = "Tag Overflow",
2875
    [TT_EXTINT | 0x1] = "External Interrupt 1",
2876
    [TT_EXTINT | 0x2] = "External Interrupt 2",
2877
    [TT_EXTINT | 0x3] = "External Interrupt 3",
2878
    [TT_EXTINT | 0x4] = "External Interrupt 4",
2879
    [TT_EXTINT | 0x5] = "External Interrupt 5",
2880
    [TT_EXTINT | 0x6] = "External Interrupt 6",
2881
    [TT_EXTINT | 0x7] = "External Interrupt 7",
2882
    [TT_EXTINT | 0x8] = "External Interrupt 8",
2883
    [TT_EXTINT | 0x9] = "External Interrupt 9",
2884
    [TT_EXTINT | 0xa] = "External Interrupt 10",
2885
    [TT_EXTINT | 0xb] = "External Interrupt 11",
2886
    [TT_EXTINT | 0xc] = "External Interrupt 12",
2887
    [TT_EXTINT | 0xd] = "External Interrupt 13",
2888
    [TT_EXTINT | 0xe] = "External Interrupt 14",
2889
    [TT_EXTINT | 0xf] = "External Interrupt 15",
2890
    [TT_TOVF] = "Tag Overflow",
2891
    [TT_CODE_ACCESS] = "Instruction Access Error",
2892
    [TT_DATA_ACCESS] = "Data Access Error",
2893
    [TT_DIV_ZERO] = "Division By Zero",
2894
    [TT_NCP_INSN] = "Coprocessor Disabled",
2895
};
2896
#endif
2735 2897

  
2736
void helper_flush(target_ulong addr)
2898
void do_interrupt(CPUState *env)
2737 2899
{
2738
    addr &= ~7;
2739
    tb_invalidate_page_range(addr, addr + 8);
2900
    int cwp, intno = env->exception_index;
2901

  
2902
#ifdef DEBUG_PCALL
2903
    if (loglevel & CPU_LOG_INT) {
2904
        static int count;
2905
        const char *name;
2906

  
2907
        if (intno < 0 || intno >= 0x100)
2908
            name = "Unknown";
2909
        else if (intno >= 0x80)
2910
            name = "Trap Instruction";
2911
        else {
2912
            name = excp_names[intno];
2913
            if (!name)
2914
                name = "Unknown";
2915
        }
2916

  
2917
        fprintf(logfile, "%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
2918
                count, name, intno,
2919
                env->pc,
2920
                env->npc, env->regwptr[6]);
2921
        cpu_dump_state(env, logfile, fprintf, 0);
2922
#if 0
2923
        {
2924
            int i;
2925
            uint8_t *ptr;
2926

  
2927
            fprintf(logfile, "       code=");
2928
            ptr = (uint8_t *)env->pc;
2929
            for(i = 0; i < 16; i++) {
2930
                fprintf(logfile, " %02x", ldub(ptr + i));
2931
            }
2932
            fprintf(logfile, "\n");
2933
        }
2934
#endif
2935
        count++;
2936
    }
2937
#endif
2938
#if !defined(CONFIG_USER_ONLY)
2939
    if (env->psret == 0) {
2940
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
2941
                  env->exception_index);
2942
        return;
2943
    }
2944
#endif
2945
    env->psret = 0;
2946
    cwp = cpu_cwp_dec(env, env->cwp - 1);
2947
    cpu_set_cwp(env, cwp);
2948
    env->regwptr[9] = env->pc;
2949
    env->regwptr[10] = env->npc;
2950
    env->psrps = env->psrs;
2951
    env->psrs = 1;
2952
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
2953
    env->pc = env->tbr;
2954
    env->npc = env->pc + 4;
2955
    env->exception_index = 0;
2740 2956
}
2957
#endif
2741 2958

  
2742 2959
#if !defined(CONFIG_USER_ONLY)
2743 2960

  

Also available in: Unified diff