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,12 +337,17 @@ typedef struct CPUSPARCState { | ||
| 337 | } while (0) | 337 | } while (0) |
| 338 | #endif | 338 | #endif |
| 339 | 339 | ||
| 340 | +/* helper.c */ | ||
| 340 | CPUSPARCState *cpu_sparc_init(const char *cpu_model); | 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 | void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, | 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 | #define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \ | 352 | #define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \ |
| 348 | (env->psref? PSR_EF : 0) | \ | 353 | (env->psref? PSR_EF : 0) | \ |
| @@ -352,7 +357,29 @@ void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); | @@ -352,7 +357,29 @@ void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); | ||
| 352 | (env->psret? PSR_ET : 0) | env->cwp) | 357 | (env->psret? PSR_ET : 0) | env->cwp) |
| 353 | 358 | ||
| 354 | #ifndef NO_CPU_IO_DEFS | 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 | static inline int cpu_cwp_inc(CPUSPARCState *env1, int cwp) | 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,10 +424,9 @@ static inline void PUT_CWP64(CPUSPARCState *env1, int cwp) | ||
| 397 | #endif | 424 | #endif |
| 398 | #endif | 425 | #endif |
| 399 | 426 | ||
| 400 | -int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc); | 427 | +/* cpu-exec.c */ |
| 401 | void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, | 428 | void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, |
| 402 | int is_asi); | 429 | int is_asi); |
| 403 | -void cpu_check_irqs(CPUSPARCState *env); | ||
| 404 | 430 | ||
| 405 | #define CPUState CPUSPARCState | 431 | #define CPUState CPUSPARCState |
| 406 | #define cpu_init cpu_sparc_init | 432 | #define cpu_init cpu_sparc_init |
target-sparc/exec.h
| @@ -23,10 +23,25 @@ static inline void regs_to_env(void) | @@ -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 | int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw, | 29 | int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw, |
| 27 | int mmu_idx, int is_softmmu); | 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 | void do_interrupt(CPUState *env); | 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 | static inline int cpu_halted(CPUState *env1) { | 45 | static inline int cpu_halted(CPUState *env1) { |
| 31 | if (!env1->halted) | 46 | if (!env1->halted) |
| 32 | return 0; | 47 | return 0; |
target-sparc/helper.c
| @@ -28,7 +28,6 @@ | @@ -28,7 +28,6 @@ | ||
| 28 | #include "cpu.h" | 28 | #include "cpu.h" |
| 29 | #include "exec-all.h" | 29 | #include "exec-all.h" |
| 30 | #include "qemu-common.h" | 30 | #include "qemu-common.h" |
| 31 | -#include "helper.h" | ||
| 32 | 31 | ||
| 33 | //#define DEBUG_MMU | 32 | //#define DEBUG_MMU |
| 34 | //#define DEBUG_FEATURES | 33 | //#define DEBUG_FEATURES |
| @@ -639,247 +638,6 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) | @@ -639,247 +638,6 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) | ||
| 639 | } | 638 | } |
| 640 | #endif | 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 | void cpu_reset(CPUSPARCState *env) | 641 | void cpu_reset(CPUSPARCState *env) |
| 884 | { | 642 | { |
| 885 | tlb_flush(env, 1); | 643 | tlb_flush(env, 1); |
target-sparc/helper.h
| @@ -179,12 +179,3 @@ VIS_CMPHELPER(cmpne); | @@ -179,12 +179,3 @@ VIS_CMPHELPER(cmpne); | ||
| 179 | #undef F_HELPER_SDQ_0_0 | 179 | #undef F_HELPER_SDQ_0_0 |
| 180 | #undef VIS_HELPER | 180 | #undef VIS_HELPER |
| 181 | #undef VIS_CMPHELPER | 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,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 | void helper_check_align(target_ulong addr, uint32_t align) | 76 | void helper_check_align(target_ulong addr, uint32_t align) |
| 72 | { | 77 | { |
| 73 | if (addr & align) { | 78 | if (addr & align) { |
| @@ -2668,7 +2673,7 @@ static inline uint64_t *get_gregset(uint64_t pstate) | @@ -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 | uint64_t pstate_regs, new_pstate_regs; | 2678 | uint64_t pstate_regs, new_pstate_regs; |
| 2674 | uint64_t *src, *dst; | 2679 | uint64_t *src, *dst; |
| @@ -2716,28 +2721,240 @@ void helper_retry(void) | @@ -2716,28 +2721,240 @@ void helper_retry(void) | ||
| 2716 | } | 2721 | } |
| 2717 | #endif | 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 | #if !defined(CONFIG_USER_ONLY) | 2959 | #if !defined(CONFIG_USER_ONLY) |
| 2743 | 2960 |