Revision f2bc7e7f target-sparc/op_helper.c
b/target-sparc/op_helper.c | ||
---|---|---|
5 | 5 |
#include "softmmu_exec.h" |
6 | 6 |
#endif /* !defined(CONFIG_USER_ONLY) */ |
7 | 7 |
|
8 |
//#define DEBUG_PCALL |
|
9 | 8 |
//#define DEBUG_MMU |
10 | 9 |
//#define DEBUG_MXCC |
11 | 10 |
//#define DEBUG_UNALIGNED |
... | ... | |
2573 | 2572 |
} |
2574 | 2573 |
} |
2575 | 2574 |
|
2576 |
static inline void change_pstate(uint64_t new_pstate)
|
|
2575 |
void change_pstate(uint64_t new_pstate) |
|
2577 | 2576 |
{ |
2578 | 2577 |
uint64_t pstate_regs, new_pstate_regs; |
2579 | 2578 |
uint64_t *src, *dst; |
... | ... | |
2620 | 2619 |
} |
2621 | 2620 |
#endif |
2622 | 2621 |
|
2623 |
void set_cwp(int new_cwp)
|
|
2622 |
void cpu_set_cwp(CPUState *env1, int new_cwp)
|
|
2624 | 2623 |
{ |
2625 | 2624 |
/* put the modified wrap registers at their proper location */ |
2626 |
if (env->cwp == (NWINDOWS - 1)) |
|
2627 |
memcpy32(env->regbase, env->regbase + NWINDOWS * 16);
|
|
2628 |
env->cwp = new_cwp; |
|
2625 |
if (env1->cwp == (NWINDOWS - 1))
|
|
2626 |
memcpy32(env1->regbase, env1->regbase + NWINDOWS * 16);
|
|
2627 |
env1->cwp = new_cwp;
|
|
2629 | 2628 |
/* put the wrap registers at their temporary location */ |
2630 | 2629 |
if (new_cwp == (NWINDOWS - 1)) |
2631 |
memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
|
|
2632 |
env->regwptr = env->regbase + (new_cwp * 16);
|
|
2633 |
REGWPTR = env->regwptr; |
|
2630 |
memcpy32(env1->regbase + NWINDOWS * 16, env1->regbase);
|
|
2631 |
env1->regwptr = env1->regbase + (new_cwp * 16);
|
|
2632 |
REGWPTR = env1->regwptr;
|
|
2634 | 2633 |
} |
2635 | 2634 |
|
2636 |
void cpu_set_cwp(CPUState *env1, int new_cwp)
|
|
2635 |
void set_cwp(int new_cwp)
|
|
2637 | 2636 |
{ |
2638 |
CPUState *saved_env; |
|
2639 |
#ifdef reg_REGWPTR |
|
2640 |
target_ulong *saved_regwptr; |
|
2641 |
#endif |
|
2642 |
|
|
2643 |
saved_env = env; |
|
2644 |
#ifdef reg_REGWPTR |
|
2645 |
saved_regwptr = REGWPTR; |
|
2646 |
#endif |
|
2647 |
env = env1; |
|
2648 |
set_cwp(new_cwp); |
|
2649 |
env = saved_env; |
|
2650 |
#ifdef reg_REGWPTR |
|
2651 |
REGWPTR = saved_regwptr; |
|
2652 |
#endif |
|
2653 |
} |
|
2654 |
|
|
2655 |
#ifdef TARGET_SPARC64 |
|
2656 |
#ifdef DEBUG_PCALL |
|
2657 |
static const char * const excp_names[0x50] = { |
|
2658 |
[TT_TFAULT] = "Instruction Access Fault", |
|
2659 |
[TT_TMISS] = "Instruction Access MMU Miss", |
|
2660 |
[TT_CODE_ACCESS] = "Instruction Access Error", |
|
2661 |
[TT_ILL_INSN] = "Illegal Instruction", |
|
2662 |
[TT_PRIV_INSN] = "Privileged Instruction", |
|
2663 |
[TT_NFPU_INSN] = "FPU Disabled", |
|
2664 |
[TT_FP_EXCP] = "FPU Exception", |
|
2665 |
[TT_TOVF] = "Tag Overflow", |
|
2666 |
[TT_CLRWIN] = "Clean Windows", |
|
2667 |
[TT_DIV_ZERO] = "Division By Zero", |
|
2668 |
[TT_DFAULT] = "Data Access Fault", |
|
2669 |
[TT_DMISS] = "Data Access MMU Miss", |
|
2670 |
[TT_DATA_ACCESS] = "Data Access Error", |
|
2671 |
[TT_DPROT] = "Data Protection Error", |
|
2672 |
[TT_UNALIGNED] = "Unaligned Memory Access", |
|
2673 |
[TT_PRIV_ACT] = "Privileged Action", |
|
2674 |
[TT_EXTINT | 0x1] = "External Interrupt 1", |
|
2675 |
[TT_EXTINT | 0x2] = "External Interrupt 2", |
|
2676 |
[TT_EXTINT | 0x3] = "External Interrupt 3", |
|
2677 |
[TT_EXTINT | 0x4] = "External Interrupt 4", |
|
2678 |
[TT_EXTINT | 0x5] = "External Interrupt 5", |
|
2679 |
[TT_EXTINT | 0x6] = "External Interrupt 6", |
|
2680 |
[TT_EXTINT | 0x7] = "External Interrupt 7", |
|
2681 |
[TT_EXTINT | 0x8] = "External Interrupt 8", |
|
2682 |
[TT_EXTINT | 0x9] = "External Interrupt 9", |
|
2683 |
[TT_EXTINT | 0xa] = "External Interrupt 10", |
|
2684 |
[TT_EXTINT | 0xb] = "External Interrupt 11", |
|
2685 |
[TT_EXTINT | 0xc] = "External Interrupt 12", |
|
2686 |
[TT_EXTINT | 0xd] = "External Interrupt 13", |
|
2687 |
[TT_EXTINT | 0xe] = "External Interrupt 14", |
|
2688 |
[TT_EXTINT | 0xf] = "External Interrupt 15", |
|
2689 |
}; |
|
2690 |
#endif |
|
2691 |
|
|
2692 |
void do_interrupt(int intno) |
|
2693 |
{ |
|
2694 |
#ifdef DEBUG_PCALL |
|
2695 |
if (loglevel & CPU_LOG_INT) { |
|
2696 |
static int count; |
|
2697 |
const char *name; |
|
2698 |
|
|
2699 |
if (intno < 0 || intno >= 0x180 || (intno > 0x4f && intno < 0x80)) |
|
2700 |
name = "Unknown"; |
|
2701 |
else if (intno >= 0x100) |
|
2702 |
name = "Trap Instruction"; |
|
2703 |
else if (intno >= 0xc0) |
|
2704 |
name = "Window Fill"; |
|
2705 |
else if (intno >= 0x80) |
|
2706 |
name = "Window Spill"; |
|
2707 |
else { |
|
2708 |
name = excp_names[intno]; |
|
2709 |
if (!name) |
|
2710 |
name = "Unknown"; |
|
2711 |
} |
|
2712 |
|
|
2713 |
fprintf(logfile, "%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64 |
|
2714 |
" SP=%016" PRIx64 "\n", |
|
2715 |
count, name, intno, |
|
2716 |
env->pc, |
|
2717 |
env->npc, env->regwptr[6]); |
|
2718 |
cpu_dump_state(env, logfile, fprintf, 0); |
|
2719 |
#if 0 |
|
2720 |
{ |
|
2721 |
int i; |
|
2722 |
uint8_t *ptr; |
|
2723 |
|
|
2724 |
fprintf(logfile, " code="); |
|
2725 |
ptr = (uint8_t *)env->pc; |
|
2726 |
for(i = 0; i < 16; i++) { |
|
2727 |
fprintf(logfile, " %02x", ldub(ptr + i)); |
|
2728 |
} |
|
2729 |
fprintf(logfile, "\n"); |
|
2730 |
} |
|
2731 |
#endif |
|
2732 |
count++; |
|
2733 |
} |
|
2734 |
#endif |
|
2735 |
#if !defined(CONFIG_USER_ONLY) |
|
2736 |
if (env->tl == MAXTL) { |
|
2737 |
cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state", |
|
2738 |
env->exception_index); |
|
2739 |
return; |
|
2740 |
} |
|
2741 |
#endif |
|
2742 |
env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) | |
|
2743 |
((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) | |
|
2744 |
GET_CWP64(env); |
|
2745 |
env->tsptr->tpc = env->pc; |
|
2746 |
env->tsptr->tnpc = env->npc; |
|
2747 |
env->tsptr->tt = intno; |
|
2748 |
change_pstate(PS_PEF | PS_PRIV | PS_AG); |
|
2749 |
|
|
2750 |
if (intno == TT_CLRWIN) |
|
2751 |
set_cwp((env->cwp - 1) & (NWINDOWS - 1)); |
|
2752 |
else if ((intno & 0x1c0) == TT_SPILL) |
|
2753 |
set_cwp((env->cwp - env->cansave - 2) & (NWINDOWS - 1)); |
|
2754 |
else if ((intno & 0x1c0) == TT_FILL) |
|
2755 |
set_cwp((env->cwp + 1) & (NWINDOWS - 1)); |
|
2756 |
env->tbr &= ~0x7fffULL; |
|
2757 |
env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5); |
|
2758 |
if (env->tl < MAXTL - 1) { |
|
2759 |
env->tl++; |
|
2760 |
} else { |
|
2761 |
env->pstate |= PS_RED; |
|
2762 |
if (env->tl != MAXTL) |
|
2763 |
env->tl++; |
|
2764 |
} |
|
2765 |
env->tsptr = &env->ts[env->tl]; |
|
2766 |
env->pc = env->tbr; |
|
2767 |
env->npc = env->pc + 4; |
|
2768 |
env->exception_index = 0; |
|
2637 |
cpu_set_cwp(env, new_cwp); |
|
2769 | 2638 |
} |
2770 |
#else |
|
2771 |
#ifdef DEBUG_PCALL |
|
2772 |
static const char * const excp_names[0x80] = { |
|
2773 |
[TT_TFAULT] = "Instruction Access Fault", |
|
2774 |
[TT_ILL_INSN] = "Illegal Instruction", |
|
2775 |
[TT_PRIV_INSN] = "Privileged Instruction", |
|
2776 |
[TT_NFPU_INSN] = "FPU Disabled", |
|
2777 |
[TT_WIN_OVF] = "Window Overflow", |
|
2778 |
[TT_WIN_UNF] = "Window Underflow", |
|
2779 |
[TT_UNALIGNED] = "Unaligned Memory Access", |
|
2780 |
[TT_FP_EXCP] = "FPU Exception", |
|
2781 |
[TT_DFAULT] = "Data Access Fault", |
|
2782 |
[TT_TOVF] = "Tag Overflow", |
|
2783 |
[TT_EXTINT | 0x1] = "External Interrupt 1", |
|
2784 |
[TT_EXTINT | 0x2] = "External Interrupt 2", |
|
2785 |
[TT_EXTINT | 0x3] = "External Interrupt 3", |
|
2786 |
[TT_EXTINT | 0x4] = "External Interrupt 4", |
|
2787 |
[TT_EXTINT | 0x5] = "External Interrupt 5", |
|
2788 |
[TT_EXTINT | 0x6] = "External Interrupt 6", |
|
2789 |
[TT_EXTINT | 0x7] = "External Interrupt 7", |
|
2790 |
[TT_EXTINT | 0x8] = "External Interrupt 8", |
|
2791 |
[TT_EXTINT | 0x9] = "External Interrupt 9", |
|
2792 |
[TT_EXTINT | 0xa] = "External Interrupt 10", |
|
2793 |
[TT_EXTINT | 0xb] = "External Interrupt 11", |
|
2794 |
[TT_EXTINT | 0xc] = "External Interrupt 12", |
|
2795 |
[TT_EXTINT | 0xd] = "External Interrupt 13", |
|
2796 |
[TT_EXTINT | 0xe] = "External Interrupt 14", |
|
2797 |
[TT_EXTINT | 0xf] = "External Interrupt 15", |
|
2798 |
[TT_TOVF] = "Tag Overflow", |
|
2799 |
[TT_CODE_ACCESS] = "Instruction Access Error", |
|
2800 |
[TT_DATA_ACCESS] = "Data Access Error", |
|
2801 |
[TT_DIV_ZERO] = "Division By Zero", |
|
2802 |
[TT_NCP_INSN] = "Coprocessor Disabled", |
|
2803 |
}; |
|
2804 |
#endif |
|
2805 | 2639 |
|
2806 |
void do_interrupt(int intno)
|
|
2640 |
void helper_flush(target_ulong addr)
|
|
2807 | 2641 |
{ |
2808 |
int cwp; |
|
2809 |
|
|
2810 |
#ifdef DEBUG_PCALL |
|
2811 |
if (loglevel & CPU_LOG_INT) { |
|
2812 |
static int count; |
|
2813 |
const char *name; |
|
2814 |
|
|
2815 |
if (intno < 0 || intno >= 0x100) |
|
2816 |
name = "Unknown"; |
|
2817 |
else if (intno >= 0x80) |
|
2818 |
name = "Trap Instruction"; |
|
2819 |
else { |
|
2820 |
name = excp_names[intno]; |
|
2821 |
if (!name) |
|
2822 |
name = "Unknown"; |
|
2823 |
} |
|
2824 |
|
|
2825 |
fprintf(logfile, "%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n", |
|
2826 |
count, name, intno, |
|
2827 |
env->pc, |
|
2828 |
env->npc, env->regwptr[6]); |
|
2829 |
cpu_dump_state(env, logfile, fprintf, 0); |
|
2830 |
#if 0 |
|
2831 |
{ |
|
2832 |
int i; |
|
2833 |
uint8_t *ptr; |
|
2834 |
|
|
2835 |
fprintf(logfile, " code="); |
|
2836 |
ptr = (uint8_t *)env->pc; |
|
2837 |
for(i = 0; i < 16; i++) { |
|
2838 |
fprintf(logfile, " %02x", ldub(ptr + i)); |
|
2839 |
} |
|
2840 |
fprintf(logfile, "\n"); |
|
2841 |
} |
|
2842 |
#endif |
|
2843 |
count++; |
|
2844 |
} |
|
2845 |
#endif |
|
2846 |
#if !defined(CONFIG_USER_ONLY) |
|
2847 |
if (env->psret == 0) { |
|
2848 |
cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", |
|
2849 |
env->exception_index); |
|
2850 |
return; |
|
2851 |
} |
|
2852 |
#endif |
|
2853 |
env->psret = 0; |
|
2854 |
cwp = (env->cwp - 1) & (NWINDOWS - 1); |
|
2855 |
set_cwp(cwp); |
|
2856 |
env->regwptr[9] = env->pc; |
|
2857 |
env->regwptr[10] = env->npc; |
|
2858 |
env->psrps = env->psrs; |
|
2859 |
env->psrs = 1; |
|
2860 |
env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4); |
|
2861 |
env->pc = env->tbr; |
|
2862 |
env->npc = env->pc + 4; |
|
2863 |
env->exception_index = 0; |
|
2642 |
addr &= ~7; |
|
2643 |
tb_invalidate_page_range(addr, addr + 8); |
|
2864 | 2644 |
} |
2865 |
#endif |
|
2866 | 2645 |
|
2867 | 2646 |
#if !defined(CONFIG_USER_ONLY) |
2868 | 2647 |
|
Also available in: Unified diff