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 | ... | ... |