Commit 91736d378b9bc6a9d7e16556216c919ba21dc5ca
1 parent
a4625612
Fix Sparc64 boot on i386 host:
- move do_interrupt() back to op_helper.c - move non-helper prototypes from helper.h to exec.h - move some prototypes from cpu.h to exec.h - do not export either set_cwp() or cpu_set_cwp() from op_helper.c, but instead provide inline functions git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5109 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
280 additions
and
273 deletions
target-sparc/cpu.h
... | ... | @@ -337,12 +337,17 @@ typedef struct CPUSPARCState { |
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,7 +357,29 @@ void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); |
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,10 +424,9 @@ static inline void PUT_CWP64(CPUSPARCState *env1, int cwp) |
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 | ... | ... |
target-sparc/exec.h
... | ... | @@ -23,10 +23,25 @@ static inline void regs_to_env(void) |
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; | ... | ... |
target-sparc/helper.c
... | ... | @@ -28,7 +28,6 @@ |
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,247 +638,6 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) |
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); | ... | ... |
target-sparc/helper.h
... | ... | @@ -179,12 +179,3 @@ VIS_CMPHELPER(cmpne); |
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); | ... | ... |
target-sparc/op_helper.c
... | ... | @@ -68,6 +68,11 @@ void helper_trapcc(target_ulong nb_trap, target_ulong do_trap) |
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,7 +2673,7 @@ static inline uint64_t *get_gregset(uint64_t pstate) |
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,28 +2721,240 @@ void helper_retry(void) |
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 | ... | ... |