Commit f2bc7e7fa175b61a20c6f10c324d7c4d68af676f
1 parent
8d96d209
Move non-op functions from op_helper.c to helper.c and vice versa.
Rearrange interrupt handling to match other targets. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4590 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
233 additions
and
243 deletions
cpu-exec.c
| @@ -333,7 +333,7 @@ int cpu_exec(CPUState *env1) | @@ -333,7 +333,7 @@ int cpu_exec(CPUState *env1) | ||
| 333 | #elif defined(TARGET_MIPS) | 333 | #elif defined(TARGET_MIPS) |
| 334 | do_interrupt(env); | 334 | do_interrupt(env); |
| 335 | #elif defined(TARGET_SPARC) | 335 | #elif defined(TARGET_SPARC) |
| 336 | - do_interrupt(env->exception_index); | 336 | + do_interrupt(env); |
| 337 | #elif defined(TARGET_ARM) | 337 | #elif defined(TARGET_ARM) |
| 338 | do_interrupt(env); | 338 | do_interrupt(env); |
| 339 | #elif defined(TARGET_SH4) | 339 | #elif defined(TARGET_SH4) |
| @@ -474,7 +474,8 @@ int cpu_exec(CPUState *env1) | @@ -474,7 +474,8 @@ int cpu_exec(CPUState *env1) | ||
| 474 | (pil == 15 || pil > env->psrpil)) || | 474 | (pil == 15 || pil > env->psrpil)) || |
| 475 | type != TT_EXTINT) { | 475 | type != TT_EXTINT) { |
| 476 | env->interrupt_request &= ~CPU_INTERRUPT_HARD; | 476 | env->interrupt_request &= ~CPU_INTERRUPT_HARD; |
| 477 | - do_interrupt(env->interrupt_index); | 477 | + env->exception_index = env->interrupt_index; |
| 478 | + do_interrupt(env); | ||
| 478 | env->interrupt_index = 0; | 479 | env->interrupt_index = 0; |
| 479 | #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) | 480 | #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) |
| 480 | cpu_check_irqs(env); | 481 | cpu_check_irqs(env); |
target-sparc/exec.h
| @@ -30,7 +30,7 @@ static inline void regs_to_env(void) | @@ -30,7 +30,7 @@ static inline void regs_to_env(void) | ||
| 30 | 30 | ||
| 31 | int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw, | 31 | int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw, |
| 32 | int mmu_idx, int is_softmmu); | 32 | int mmu_idx, int is_softmmu); |
| 33 | -void do_interrupt(int intno); | 33 | +void do_interrupt(CPUState *env); |
| 34 | 34 | ||
| 35 | static inline int cpu_halted(CPUState *env1) { | 35 | static inline int cpu_halted(CPUState *env1) { |
| 36 | if (!env1->halted) | 36 | if (!env1->halted) |
target-sparc/helper.c
| @@ -32,6 +32,7 @@ | @@ -32,6 +32,7 @@ | ||
| 32 | 32 | ||
| 33 | //#define DEBUG_MMU | 33 | //#define DEBUG_MMU |
| 34 | //#define DEBUG_FEATURES | 34 | //#define DEBUG_FEATURES |
| 35 | +//#define DEBUG_PCALL | ||
| 35 | 36 | ||
| 36 | typedef struct sparc_def_t sparc_def_t; | 37 | typedef struct sparc_def_t sparc_def_t; |
| 37 | 38 | ||
| @@ -651,6 +652,220 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) | @@ -651,6 +652,220 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) | ||
| 651 | } | 652 | } |
| 652 | #endif | 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 | void memcpy32(target_ulong *dst, const target_ulong *src) | 869 | void memcpy32(target_ulong *dst, const target_ulong *src) |
| 655 | { | 870 | { |
| 656 | dst[0] = src[0]; | 871 | dst[0] = src[0]; |
| @@ -663,12 +878,6 @@ void memcpy32(target_ulong *dst, const target_ulong *src) | @@ -663,12 +878,6 @@ void memcpy32(target_ulong *dst, const target_ulong *src) | ||
| 663 | dst[7] = src[7]; | 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 | void cpu_reset(CPUSPARCState *env) | 881 | void cpu_reset(CPUSPARCState *env) |
| 673 | { | 882 | { |
| 674 | tlb_flush(env, 1); | 883 | tlb_flush(env, 1); |
target-sparc/helper.h
| @@ -183,6 +183,7 @@ void cpu_lock(void); | @@ -183,6 +183,7 @@ void cpu_lock(void); | ||
| 183 | void cpu_unlock(void); | 183 | void cpu_unlock(void); |
| 184 | void cpu_loop_exit(void); | 184 | void cpu_loop_exit(void); |
| 185 | void set_cwp(int new_cwp); | 185 | void set_cwp(int new_cwp); |
| 186 | +void change_pstate(uint64_t new_pstate); | ||
| 186 | void memcpy32(target_ulong *dst, const target_ulong *src); | 187 | void memcpy32(target_ulong *dst, const target_ulong *src); |
| 187 | target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev); | 188 | target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev); |
| 188 | void dump_mmu(CPUState *env); | 189 | void dump_mmu(CPUState *env); |
target-sparc/op_helper.c
| @@ -5,7 +5,6 @@ | @@ -5,7 +5,6 @@ | ||
| 5 | #include "softmmu_exec.h" | 5 | #include "softmmu_exec.h" |
| 6 | #endif /* !defined(CONFIG_USER_ONLY) */ | 6 | #endif /* !defined(CONFIG_USER_ONLY) */ |
| 7 | 7 | ||
| 8 | -//#define DEBUG_PCALL | ||
| 9 | //#define DEBUG_MMU | 8 | //#define DEBUG_MMU |
| 10 | //#define DEBUG_MXCC | 9 | //#define DEBUG_MXCC |
| 11 | //#define DEBUG_UNALIGNED | 10 | //#define DEBUG_UNALIGNED |
| @@ -2573,7 +2572,7 @@ static inline uint64_t *get_gregset(uint64_t pstate) | @@ -2573,7 +2572,7 @@ static inline uint64_t *get_gregset(uint64_t pstate) | ||
| 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 | uint64_t pstate_regs, new_pstate_regs; | 2577 | uint64_t pstate_regs, new_pstate_regs; |
| 2579 | uint64_t *src, *dst; | 2578 | uint64_t *src, *dst; |
| @@ -2620,249 +2619,29 @@ void helper_retry(void) | @@ -2620,249 +2619,29 @@ void helper_retry(void) | ||
| 2620 | } | 2619 | } |
| 2621 | #endif | 2620 | #endif |
| 2622 | 2621 | ||
| 2623 | -void set_cwp(int new_cwp) | 2622 | +void cpu_set_cwp(CPUState *env1, int new_cwp) |
| 2624 | { | 2623 | { |
| 2625 | /* put the modified wrap registers at their proper location */ | 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 | /* put the wrap registers at their temporary location */ | 2628 | /* put the wrap registers at their temporary location */ |
| 2630 | if (new_cwp == (NWINDOWS - 1)) | 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 | #if !defined(CONFIG_USER_ONLY) | 2646 | #if !defined(CONFIG_USER_ONLY) |
| 2868 | 2647 |