Revision f2bc7e7f target-sparc/helper.c

b/target-sparc/helper.c
32 32

  
33 33
//#define DEBUG_MMU
34 34
//#define DEBUG_FEATURES
35
//#define DEBUG_PCALL
35 36

  
36 37
typedef struct sparc_def_t sparc_def_t;
37 38

  
......
651 652
}
652 653
#endif
653 654

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

  
692
void do_interrupt(CPUState *env)
693
{
694
    int intno = env->exception_index;
695

  
696
#ifdef DEBUG_PCALL
697
    if (loglevel & CPU_LOG_INT) {
698
        static int count;
699
        const char *name;
700

  
701
        if (intno < 0 || intno >= 0x180 || (intno > 0x4f && intno < 0x80))
702
            name = "Unknown";
703
        else if (intno >= 0x100)
704
            name = "Trap Instruction";
705
        else if (intno >= 0xc0)
706
            name = "Window Fill";
707
        else if (intno >= 0x80)
708
            name = "Window Spill";
709
        else {
710
            name = excp_names[intno];
711
            if (!name)
712
                name = "Unknown";
713
        }
714

  
715
        fprintf(logfile, "%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
716
                " SP=%016" PRIx64 "\n",
717
                count, name, intno,
718
                env->pc,
719
                env->npc, env->regwptr[6]);
720
        cpu_dump_state(env, logfile, fprintf, 0);
721
#if 0
722
        {
723
            int i;
724
            uint8_t *ptr;
725

  
726
            fprintf(logfile, "       code=");
727
            ptr = (uint8_t *)env->pc;
728
            for(i = 0; i < 16; i++) {
729
                fprintf(logfile, " %02x", ldub(ptr + i));
730
            }
731
            fprintf(logfile, "\n");
732
        }
733
#endif
734
        count++;
735
    }
736
#endif
737
#if !defined(CONFIG_USER_ONLY)
738
    if (env->tl == MAXTL) {
739
        cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state",
740
                  env->exception_index);
741
        return;
742
    }
743
#endif
744
    env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
745
        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
746
        GET_CWP64(env);
747
    env->tsptr->tpc = env->pc;
748
    env->tsptr->tnpc = env->npc;
749
    env->tsptr->tt = intno;
750
    change_pstate(PS_PEF | PS_PRIV | PS_AG);
751

  
752
    if (intno == TT_CLRWIN)
753
        cpu_set_cwp(env, (env->cwp - 1) & (NWINDOWS - 1));
754
    else if ((intno & 0x1c0) == TT_SPILL)
755
        cpu_set_cwp(env, (env->cwp - env->cansave - 2) & (NWINDOWS - 1));
756
    else if ((intno & 0x1c0) == TT_FILL)
757
        cpu_set_cwp(env, (env->cwp + 1) & (NWINDOWS - 1));
758
    env->tbr &= ~0x7fffULL;
759
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
760
    if (env->tl < MAXTL - 1) {
761
        env->tl++;
762
    } else {
763
        env->pstate |= PS_RED;
764
        if (env->tl != MAXTL)
765
            env->tl++;
766
    }
767
    env->tsptr = &env->ts[env->tl];
768
    env->pc = env->tbr;
769
    env->npc = env->pc + 4;
770
    env->exception_index = 0;
771
}
772
#else
773
#ifdef DEBUG_PCALL
774
static const char * const excp_names[0x80] = {
775
    [TT_TFAULT] = "Instruction Access Fault",
776
    [TT_ILL_INSN] = "Illegal Instruction",
777
    [TT_PRIV_INSN] = "Privileged Instruction",
778
    [TT_NFPU_INSN] = "FPU Disabled",
779
    [TT_WIN_OVF] = "Window Overflow",
780
    [TT_WIN_UNF] = "Window Underflow",
781
    [TT_UNALIGNED] = "Unaligned Memory Access",
782
    [TT_FP_EXCP] = "FPU Exception",
783
    [TT_DFAULT] = "Data Access Fault",
784
    [TT_TOVF] = "Tag Overflow",
785
    [TT_EXTINT | 0x1] = "External Interrupt 1",
786
    [TT_EXTINT | 0x2] = "External Interrupt 2",
787
    [TT_EXTINT | 0x3] = "External Interrupt 3",
788
    [TT_EXTINT | 0x4] = "External Interrupt 4",
789
    [TT_EXTINT | 0x5] = "External Interrupt 5",
790
    [TT_EXTINT | 0x6] = "External Interrupt 6",
791
    [TT_EXTINT | 0x7] = "External Interrupt 7",
792
    [TT_EXTINT | 0x8] = "External Interrupt 8",
793
    [TT_EXTINT | 0x9] = "External Interrupt 9",
794
    [TT_EXTINT | 0xa] = "External Interrupt 10",
795
    [TT_EXTINT | 0xb] = "External Interrupt 11",
796
    [TT_EXTINT | 0xc] = "External Interrupt 12",
797
    [TT_EXTINT | 0xd] = "External Interrupt 13",
798
    [TT_EXTINT | 0xe] = "External Interrupt 14",
799
    [TT_EXTINT | 0xf] = "External Interrupt 15",
800
    [TT_TOVF] = "Tag Overflow",
801
    [TT_CODE_ACCESS] = "Instruction Access Error",
802
    [TT_DATA_ACCESS] = "Data Access Error",
803
    [TT_DIV_ZERO] = "Division By Zero",
804
    [TT_NCP_INSN] = "Coprocessor Disabled",
805
};
806
#endif
807

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

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

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

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

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

  
654 869
void memcpy32(target_ulong *dst, const target_ulong *src)
655 870
{
656 871
    dst[0] = src[0];
......
663 878
    dst[7] = src[7];
664 879
}
665 880

  
666
void helper_flush(target_ulong addr)
667
{
668
    addr &= ~7;
669
    tb_invalidate_page_range(addr, addr + 8);
670
}
671

  
672 881
void cpu_reset(CPUSPARCState *env)
673 882
{
674 883
    tlb_flush(env, 1);

Also available in: Unified diff