Revision 91736d37 target-sparc/helper.c

b/target-sparc/helper.c
28 28
#include "cpu.h"
29 29
#include "exec-all.h"
30 30
#include "qemu-common.h"
31
#include "helper.h"
32 31

  
33 32
//#define DEBUG_MMU
34 33
//#define DEBUG_FEATURES
......
639 638
}
640 639
#endif
641 640

  
642
#ifdef TARGET_SPARC64
643
#ifdef DEBUG_PCALL
644
static const char * const excp_names[0x80] = {
645
    [TT_TFAULT] = "Instruction Access Fault",
646
    [TT_TMISS] = "Instruction Access MMU Miss",
647
    [TT_CODE_ACCESS] = "Instruction Access Error",
648
    [TT_ILL_INSN] = "Illegal Instruction",
649
    [TT_PRIV_INSN] = "Privileged Instruction",
650
    [TT_NFPU_INSN] = "FPU Disabled",
651
    [TT_FP_EXCP] = "FPU Exception",
652
    [TT_TOVF] = "Tag Overflow",
653
    [TT_CLRWIN] = "Clean Windows",
654
    [TT_DIV_ZERO] = "Division By Zero",
655
    [TT_DFAULT] = "Data Access Fault",
656
    [TT_DMISS] = "Data Access MMU Miss",
657
    [TT_DATA_ACCESS] = "Data Access Error",
658
    [TT_DPROT] = "Data Protection Error",
659
    [TT_UNALIGNED] = "Unaligned Memory Access",
660
    [TT_PRIV_ACT] = "Privileged Action",
661
    [TT_EXTINT | 0x1] = "External Interrupt 1",
662
    [TT_EXTINT | 0x2] = "External Interrupt 2",
663
    [TT_EXTINT | 0x3] = "External Interrupt 3",
664
    [TT_EXTINT | 0x4] = "External Interrupt 4",
665
    [TT_EXTINT | 0x5] = "External Interrupt 5",
666
    [TT_EXTINT | 0x6] = "External Interrupt 6",
667
    [TT_EXTINT | 0x7] = "External Interrupt 7",
668
    [TT_EXTINT | 0x8] = "External Interrupt 8",
669
    [TT_EXTINT | 0x9] = "External Interrupt 9",
670
    [TT_EXTINT | 0xa] = "External Interrupt 10",
671
    [TT_EXTINT | 0xb] = "External Interrupt 11",
672
    [TT_EXTINT | 0xc] = "External Interrupt 12",
673
    [TT_EXTINT | 0xd] = "External Interrupt 13",
674
    [TT_EXTINT | 0xe] = "External Interrupt 14",
675
    [TT_EXTINT | 0xf] = "External Interrupt 15",
676
};
677
#endif
678

  
679
void do_interrupt(CPUState *env)
680
{
681
    int intno = env->exception_index;
682

  
683
#ifdef DEBUG_PCALL
684
    if (loglevel & CPU_LOG_INT) {
685
        static int count;
686
        const char *name;
687

  
688
        if (intno < 0 || intno >= 0x180)
689
            name = "Unknown";
690
        else if (intno >= 0x100)
691
            name = "Trap Instruction";
692
        else if (intno >= 0xc0)
693
            name = "Window Fill";
694
        else if (intno >= 0x80)
695
            name = "Window Spill";
696
        else {
697
            name = excp_names[intno];
698
            if (!name)
699
                name = "Unknown";
700
        }
701

  
702
        fprintf(logfile, "%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
703
                " SP=%016" PRIx64 "\n",
704
                count, name, intno,
705
                env->pc,
706
                env->npc, env->regwptr[6]);
707
        cpu_dump_state(env, logfile, fprintf, 0);
708
#if 0
709
        {
710
            int i;
711
            uint8_t *ptr;
712

  
713
            fprintf(logfile, "       code=");
714
            ptr = (uint8_t *)env->pc;
715
            for(i = 0; i < 16; i++) {
716
                fprintf(logfile, " %02x", ldub(ptr + i));
717
            }
718
            fprintf(logfile, "\n");
719
        }
720
#endif
721
        count++;
722
    }
723
#endif
724
#if !defined(CONFIG_USER_ONLY)
725
    if (env->tl >= env->maxtl) {
726
        cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
727
                  " Error state", env->exception_index, env->tl, env->maxtl);
728
        return;
729
    }
730
#endif
731
    if (env->tl < env->maxtl - 1) {
732
        env->tl++;
733
    } else {
734
        env->pstate |= PS_RED;
735
        if (env->tl < env->maxtl)
736
            env->tl++;
737
    }
738
    env->tsptr = &env->ts[env->tl & MAXTL_MASK];
739
    env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
740
        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
741
        GET_CWP64(env);
742
    env->tsptr->tpc = env->pc;
743
    env->tsptr->tnpc = env->npc;
744
    env->tsptr->tt = intno;
745
    if (!(env->def->features & CPU_FEATURE_GL)) {
746
        switch (intno) {
747
        case TT_IVEC:
748
            change_pstate(PS_PEF | PS_PRIV | PS_IG);
749
            break;
750
        case TT_TFAULT:
751
        case TT_TMISS:
752
        case TT_DFAULT:
753
        case TT_DMISS:
754
        case TT_DPROT:
755
            change_pstate(PS_PEF | PS_PRIV | PS_MG);
756
            break;
757
        default:
758
            change_pstate(PS_PEF | PS_PRIV | PS_AG);
759
            break;
760
        }
761
    }
762
    if (intno == TT_CLRWIN)
763
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
764
    else if ((intno & 0x1c0) == TT_SPILL)
765
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
766
    else if ((intno & 0x1c0) == TT_FILL)
767
        cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
768
    env->tbr &= ~0x7fffULL;
769
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
770
    env->pc = env->tbr;
771
    env->npc = env->pc + 4;
772
    env->exception_index = 0;
773
}
774
#else
775
#ifdef DEBUG_PCALL
776
static const char * const excp_names[0x80] = {
777
    [TT_TFAULT] = "Instruction Access Fault",
778
    [TT_ILL_INSN] = "Illegal Instruction",
779
    [TT_PRIV_INSN] = "Privileged Instruction",
780
    [TT_NFPU_INSN] = "FPU Disabled",
781
    [TT_WIN_OVF] = "Window Overflow",
782
    [TT_WIN_UNF] = "Window Underflow",
783
    [TT_UNALIGNED] = "Unaligned Memory Access",
784
    [TT_FP_EXCP] = "FPU Exception",
785
    [TT_DFAULT] = "Data Access Fault",
786
    [TT_TOVF] = "Tag Overflow",
787
    [TT_EXTINT | 0x1] = "External Interrupt 1",
788
    [TT_EXTINT | 0x2] = "External Interrupt 2",
789
    [TT_EXTINT | 0x3] = "External Interrupt 3",
790
    [TT_EXTINT | 0x4] = "External Interrupt 4",
791
    [TT_EXTINT | 0x5] = "External Interrupt 5",
792
    [TT_EXTINT | 0x6] = "External Interrupt 6",
793
    [TT_EXTINT | 0x7] = "External Interrupt 7",
794
    [TT_EXTINT | 0x8] = "External Interrupt 8",
795
    [TT_EXTINT | 0x9] = "External Interrupt 9",
796
    [TT_EXTINT | 0xa] = "External Interrupt 10",
797
    [TT_EXTINT | 0xb] = "External Interrupt 11",
798
    [TT_EXTINT | 0xc] = "External Interrupt 12",
799
    [TT_EXTINT | 0xd] = "External Interrupt 13",
800
    [TT_EXTINT | 0xe] = "External Interrupt 14",
801
    [TT_EXTINT | 0xf] = "External Interrupt 15",
802
    [TT_TOVF] = "Tag Overflow",
803
    [TT_CODE_ACCESS] = "Instruction Access Error",
804
    [TT_DATA_ACCESS] = "Data Access Error",
805
    [TT_DIV_ZERO] = "Division By Zero",
806
    [TT_NCP_INSN] = "Coprocessor Disabled",
807
};
808
#endif
809

  
810
void do_interrupt(CPUState *env)
811
{
812
    int cwp, intno = env->exception_index;
813

  
814
#ifdef DEBUG_PCALL
815
    if (loglevel & CPU_LOG_INT) {
816
        static int count;
817
        const char *name;
818

  
819
        if (intno < 0 || intno >= 0x100)
820
            name = "Unknown";
821
        else if (intno >= 0x80)
822
            name = "Trap Instruction";
823
        else {
824
            name = excp_names[intno];
825
            if (!name)
826
                name = "Unknown";
827
        }
828

  
829
        fprintf(logfile, "%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
830
                count, name, intno,
831
                env->pc,
832
                env->npc, env->regwptr[6]);
833
        cpu_dump_state(env, logfile, fprintf, 0);
834
#if 0
835
        {
836
            int i;
837
            uint8_t *ptr;
838

  
839
            fprintf(logfile, "       code=");
840
            ptr = (uint8_t *)env->pc;
841
            for(i = 0; i < 16; i++) {
842
                fprintf(logfile, " %02x", ldub(ptr + i));
843
            }
844
            fprintf(logfile, "\n");
845
        }
846
#endif
847
        count++;
848
    }
849
#endif
850
#if !defined(CONFIG_USER_ONLY)
851
    if (env->psret == 0) {
852
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
853
                  env->exception_index);
854
        return;
855
    }
856
#endif
857
    env->psret = 0;
858
    cwp = cpu_cwp_dec(env, env->cwp - 1);
859
    cpu_set_cwp(env, cwp);
860
    env->regwptr[9] = env->pc;
861
    env->regwptr[10] = env->npc;
862
    env->psrps = env->psrs;
863
    env->psrs = 1;
864
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
865
    env->pc = env->tbr;
866
    env->npc = env->pc + 4;
867
    env->exception_index = 0;
868
}
869
#endif
870

  
871
void memcpy32(target_ulong *dst, const target_ulong *src)
872
{
873
    dst[0] = src[0];
874
    dst[1] = src[1];
875
    dst[2] = src[2];
876
    dst[3] = src[3];
877
    dst[4] = src[4];
878
    dst[5] = src[5];
879
    dst[6] = src[6];
880
    dst[7] = src[7];
881
}
882

  
883 641
void cpu_reset(CPUSPARCState *env)
884 642
{
885 643
    tlb_flush(env, 1);

Also available in: Unified diff