Revision 91736d37
b/target-sparc/cpu.h | ||
---|---|---|
337 | 337 |
} while (0) |
338 | 338 |
#endif |
339 | 339 |
|
340 |
/* helper.c */ |
|
340 | 341 |
CPUSPARCState *cpu_sparc_init(const char *cpu_model); |
341 |
void gen_intermediate_code_init(CPUSPARCState *env); |
|
342 |
int cpu_sparc_exec(CPUSPARCState *s); |
|
342 |
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); |
|
343 | 343 |
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, |
344 | 344 |
...)); |
345 |
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); |
|
345 |
|
|
346 |
/* translate.c */ |
|
347 |
void gen_intermediate_code_init(CPUSPARCState *env); |
|
348 |
|
|
349 |
/* cpu-exec.c */ |
|
350 |
int cpu_sparc_exec(CPUSPARCState *s); |
|
346 | 351 |
|
347 | 352 |
#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \ |
348 | 353 |
(env->psref? PSR_EF : 0) | \ |
... | ... | |
352 | 357 |
(env->psret? PSR_ET : 0) | env->cwp) |
353 | 358 |
|
354 | 359 |
#ifndef NO_CPU_IO_DEFS |
355 |
void cpu_set_cwp(CPUSPARCState *env1, int new_cwp); |
|
360 |
static inline void memcpy32(target_ulong *dst, const target_ulong *src) |
|
361 |
{ |
|
362 |
dst[0] = src[0]; |
|
363 |
dst[1] = src[1]; |
|
364 |
dst[2] = src[2]; |
|
365 |
dst[3] = src[3]; |
|
366 |
dst[4] = src[4]; |
|
367 |
dst[5] = src[5]; |
|
368 |
dst[6] = src[6]; |
|
369 |
dst[7] = src[7]; |
|
370 |
} |
|
371 |
|
|
372 |
static inline void cpu_set_cwp(CPUSPARCState *env1, int new_cwp) |
|
373 |
{ |
|
374 |
/* put the modified wrap registers at their proper location */ |
|
375 |
if (env1->cwp == env1->nwindows - 1) |
|
376 |
memcpy32(env1->regbase, env1->regbase + env1->nwindows * 16); |
|
377 |
env1->cwp = new_cwp; |
|
378 |
/* put the wrap registers at their temporary location */ |
|
379 |
if (new_cwp == env1->nwindows - 1) |
|
380 |
memcpy32(env1->regbase + env1->nwindows * 16, env1->regbase); |
|
381 |
env1->regwptr = env1->regbase + (new_cwp * 16); |
|
382 |
} |
|
356 | 383 |
|
357 | 384 |
static inline int cpu_cwp_inc(CPUSPARCState *env1, int cwp) |
358 | 385 |
{ |
... | ... | |
397 | 424 |
#endif |
398 | 425 |
#endif |
399 | 426 |
|
400 |
int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
|
|
427 |
/* cpu-exec.c */
|
|
401 | 428 |
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, |
402 | 429 |
int is_asi); |
403 |
void cpu_check_irqs(CPUSPARCState *env); |
|
404 | 430 |
|
405 | 431 |
#define CPUState CPUSPARCState |
406 | 432 |
#define cpu_init cpu_sparc_init |
b/target-sparc/exec.h | ||
---|---|---|
23 | 23 |
{ |
24 | 24 |
} |
25 | 25 |
|
26 |
/* helper.c */ |
|
27 |
void cpu_lock(void); |
|
28 |
void cpu_unlock(void); |
|
26 | 29 |
int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw, |
27 | 30 |
int mmu_idx, int is_softmmu); |
31 |
target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev); |
|
32 |
void dump_mmu(CPUState *env); |
|
33 |
void memcpy32(target_ulong *dst, const target_ulong *src); |
|
34 |
|
|
35 |
/* op_helper.c */ |
|
28 | 36 |
void do_interrupt(CPUState *env); |
29 | 37 |
|
38 |
/* cpu-exec.c */ |
|
39 |
void cpu_loop_exit(void); |
|
40 |
int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc); |
|
41 |
|
|
42 |
/* sun4m.c */ |
|
43 |
void cpu_check_irqs(CPUSPARCState *env); |
|
44 |
|
|
30 | 45 |
static inline int cpu_halted(CPUState *env1) { |
31 | 46 |
if (!env1->halted) |
32 | 47 |
return 0; |
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); |
b/target-sparc/helper.h | ||
---|---|---|
179 | 179 |
#undef F_HELPER_SDQ_0_0 |
180 | 180 |
#undef VIS_HELPER |
181 | 181 |
#undef VIS_CMPHELPER |
182 |
|
|
183 |
void cpu_lock(void); |
|
184 |
void cpu_unlock(void); |
|
185 |
void cpu_loop_exit(void); |
|
186 |
void set_cwp(int new_cwp); |
|
187 |
void change_pstate(uint64_t new_pstate); |
|
188 |
void memcpy32(target_ulong *dst, const target_ulong *src); |
|
189 |
target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev); |
|
190 |
void dump_mmu(CPUState *env); |
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