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
This commit is contained in:
		
							parent
							
								
									a46256129e
								
							
						
					
					
						commit
						91736d378b
					
				@ -337,12 +337,17 @@ typedef struct CPUSPARCState {
 | 
			
		||||
    } while (0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* helper.c */
 | 
			
		||||
CPUSPARCState *cpu_sparc_init(const char *cpu_model);
 | 
			
		||||
void gen_intermediate_code_init(CPUSPARCState *env);
 | 
			
		||||
int cpu_sparc_exec(CPUSPARCState *s);
 | 
			
		||||
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
 | 
			
		||||
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
 | 
			
		||||
                                                 ...));
 | 
			
		||||
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
 | 
			
		||||
 | 
			
		||||
/* translate.c */
 | 
			
		||||
void gen_intermediate_code_init(CPUSPARCState *env);
 | 
			
		||||
 | 
			
		||||
/* cpu-exec.c */
 | 
			
		||||
int cpu_sparc_exec(CPUSPARCState *s);
 | 
			
		||||
 | 
			
		||||
#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) |             \
 | 
			
		||||
                      (env->psref? PSR_EF : 0) |                        \
 | 
			
		||||
@ -352,7 +357,29 @@ void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
 | 
			
		||||
                      (env->psret? PSR_ET : 0) | env->cwp)
 | 
			
		||||
 | 
			
		||||
#ifndef NO_CPU_IO_DEFS
 | 
			
		||||
void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
 | 
			
		||||
static inline void memcpy32(target_ulong *dst, const target_ulong *src)
 | 
			
		||||
{
 | 
			
		||||
    dst[0] = src[0];
 | 
			
		||||
    dst[1] = src[1];
 | 
			
		||||
    dst[2] = src[2];
 | 
			
		||||
    dst[3] = src[3];
 | 
			
		||||
    dst[4] = src[4];
 | 
			
		||||
    dst[5] = src[5];
 | 
			
		||||
    dst[6] = src[6];
 | 
			
		||||
    dst[7] = src[7];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void cpu_set_cwp(CPUSPARCState *env1, int new_cwp)
 | 
			
		||||
{
 | 
			
		||||
    /* put the modified wrap registers at their proper location */
 | 
			
		||||
    if (env1->cwp == env1->nwindows - 1)
 | 
			
		||||
        memcpy32(env1->regbase, env1->regbase + env1->nwindows * 16);
 | 
			
		||||
    env1->cwp = new_cwp;
 | 
			
		||||
    /* put the wrap registers at their temporary location */
 | 
			
		||||
    if (new_cwp == env1->nwindows - 1)
 | 
			
		||||
        memcpy32(env1->regbase + env1->nwindows * 16, env1->regbase);
 | 
			
		||||
    env1->regwptr = env1->regbase + (new_cwp * 16);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int cpu_cwp_inc(CPUSPARCState *env1, int cwp)
 | 
			
		||||
{
 | 
			
		||||
@ -397,10 +424,9 @@ static inline void PUT_CWP64(CPUSPARCState *env1, int cwp)
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
 | 
			
		||||
/* cpu-exec.c */
 | 
			
		||||
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
 | 
			
		||||
                          int is_asi);
 | 
			
		||||
void cpu_check_irqs(CPUSPARCState *env);
 | 
			
		||||
 | 
			
		||||
#define CPUState CPUSPARCState
 | 
			
		||||
#define cpu_init cpu_sparc_init
 | 
			
		||||
 | 
			
		||||
@ -23,10 +23,25 @@ static inline void regs_to_env(void)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* helper.c */
 | 
			
		||||
void cpu_lock(void);
 | 
			
		||||
void cpu_unlock(void);
 | 
			
		||||
int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw,
 | 
			
		||||
                               int mmu_idx, int is_softmmu);
 | 
			
		||||
target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev);
 | 
			
		||||
void dump_mmu(CPUState *env);
 | 
			
		||||
void memcpy32(target_ulong *dst, const target_ulong *src);
 | 
			
		||||
 | 
			
		||||
/* op_helper.c */
 | 
			
		||||
void do_interrupt(CPUState *env);
 | 
			
		||||
 | 
			
		||||
/* cpu-exec.c */
 | 
			
		||||
void cpu_loop_exit(void);
 | 
			
		||||
int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
 | 
			
		||||
 | 
			
		||||
/* sun4m.c */
 | 
			
		||||
void cpu_check_irqs(CPUSPARCState *env);
 | 
			
		||||
 | 
			
		||||
static inline int cpu_halted(CPUState *env1) {
 | 
			
		||||
    if (!env1->halted)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,6 @@
 | 
			
		||||
#include "cpu.h"
 | 
			
		||||
#include "exec-all.h"
 | 
			
		||||
#include "qemu-common.h"
 | 
			
		||||
#include "helper.h"
 | 
			
		||||
 | 
			
		||||
//#define DEBUG_MMU
 | 
			
		||||
//#define DEBUG_FEATURES
 | 
			
		||||
@ -639,247 +638,6 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef TARGET_SPARC64
 | 
			
		||||
#ifdef DEBUG_PCALL
 | 
			
		||||
static const char * const excp_names[0x80] = {
 | 
			
		||||
    [TT_TFAULT] = "Instruction Access Fault",
 | 
			
		||||
    [TT_TMISS] = "Instruction Access MMU Miss",
 | 
			
		||||
    [TT_CODE_ACCESS] = "Instruction Access Error",
 | 
			
		||||
    [TT_ILL_INSN] = "Illegal Instruction",
 | 
			
		||||
    [TT_PRIV_INSN] = "Privileged Instruction",
 | 
			
		||||
    [TT_NFPU_INSN] = "FPU Disabled",
 | 
			
		||||
    [TT_FP_EXCP] = "FPU Exception",
 | 
			
		||||
    [TT_TOVF] = "Tag Overflow",
 | 
			
		||||
    [TT_CLRWIN] = "Clean Windows",
 | 
			
		||||
    [TT_DIV_ZERO] = "Division By Zero",
 | 
			
		||||
    [TT_DFAULT] = "Data Access Fault",
 | 
			
		||||
    [TT_DMISS] = "Data Access MMU Miss",
 | 
			
		||||
    [TT_DATA_ACCESS] = "Data Access Error",
 | 
			
		||||
    [TT_DPROT] = "Data Protection Error",
 | 
			
		||||
    [TT_UNALIGNED] = "Unaligned Memory Access",
 | 
			
		||||
    [TT_PRIV_ACT] = "Privileged Action",
 | 
			
		||||
    [TT_EXTINT | 0x1] = "External Interrupt 1",
 | 
			
		||||
    [TT_EXTINT | 0x2] = "External Interrupt 2",
 | 
			
		||||
    [TT_EXTINT | 0x3] = "External Interrupt 3",
 | 
			
		||||
    [TT_EXTINT | 0x4] = "External Interrupt 4",
 | 
			
		||||
    [TT_EXTINT | 0x5] = "External Interrupt 5",
 | 
			
		||||
    [TT_EXTINT | 0x6] = "External Interrupt 6",
 | 
			
		||||
    [TT_EXTINT | 0x7] = "External Interrupt 7",
 | 
			
		||||
    [TT_EXTINT | 0x8] = "External Interrupt 8",
 | 
			
		||||
    [TT_EXTINT | 0x9] = "External Interrupt 9",
 | 
			
		||||
    [TT_EXTINT | 0xa] = "External Interrupt 10",
 | 
			
		||||
    [TT_EXTINT | 0xb] = "External Interrupt 11",
 | 
			
		||||
    [TT_EXTINT | 0xc] = "External Interrupt 12",
 | 
			
		||||
    [TT_EXTINT | 0xd] = "External Interrupt 13",
 | 
			
		||||
    [TT_EXTINT | 0xe] = "External Interrupt 14",
 | 
			
		||||
    [TT_EXTINT | 0xf] = "External Interrupt 15",
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void do_interrupt(CPUState *env)
 | 
			
		||||
{
 | 
			
		||||
    int intno = env->exception_index;
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_PCALL
 | 
			
		||||
    if (loglevel & CPU_LOG_INT) {
 | 
			
		||||
        static int count;
 | 
			
		||||
        const char *name;
 | 
			
		||||
 | 
			
		||||
        if (intno < 0 || intno >= 0x180)
 | 
			
		||||
            name = "Unknown";
 | 
			
		||||
        else if (intno >= 0x100)
 | 
			
		||||
            name = "Trap Instruction";
 | 
			
		||||
        else if (intno >= 0xc0)
 | 
			
		||||
            name = "Window Fill";
 | 
			
		||||
        else if (intno >= 0x80)
 | 
			
		||||
            name = "Window Spill";
 | 
			
		||||
        else {
 | 
			
		||||
            name = excp_names[intno];
 | 
			
		||||
            if (!name)
 | 
			
		||||
                name = "Unknown";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fprintf(logfile, "%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
 | 
			
		||||
                " SP=%016" PRIx64 "\n",
 | 
			
		||||
                count, name, intno,
 | 
			
		||||
                env->pc,
 | 
			
		||||
                env->npc, env->regwptr[6]);
 | 
			
		||||
        cpu_dump_state(env, logfile, fprintf, 0);
 | 
			
		||||
#if 0
 | 
			
		||||
        {
 | 
			
		||||
            int i;
 | 
			
		||||
            uint8_t *ptr;
 | 
			
		||||
 | 
			
		||||
            fprintf(logfile, "       code=");
 | 
			
		||||
            ptr = (uint8_t *)env->pc;
 | 
			
		||||
            for(i = 0; i < 16; i++) {
 | 
			
		||||
                fprintf(logfile, " %02x", ldub(ptr + i));
 | 
			
		||||
            }
 | 
			
		||||
            fprintf(logfile, "\n");
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        count++;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
#if !defined(CONFIG_USER_ONLY)
 | 
			
		||||
    if (env->tl >= env->maxtl) {
 | 
			
		||||
        cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
 | 
			
		||||
                  " Error state", env->exception_index, env->tl, env->maxtl);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    if (env->tl < env->maxtl - 1) {
 | 
			
		||||
        env->tl++;
 | 
			
		||||
    } else {
 | 
			
		||||
        env->pstate |= PS_RED;
 | 
			
		||||
        if (env->tl < env->maxtl)
 | 
			
		||||
            env->tl++;
 | 
			
		||||
    }
 | 
			
		||||
    env->tsptr = &env->ts[env->tl & MAXTL_MASK];
 | 
			
		||||
    env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
 | 
			
		||||
        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
 | 
			
		||||
        GET_CWP64(env);
 | 
			
		||||
    env->tsptr->tpc = env->pc;
 | 
			
		||||
    env->tsptr->tnpc = env->npc;
 | 
			
		||||
    env->tsptr->tt = intno;
 | 
			
		||||
    if (!(env->def->features & CPU_FEATURE_GL)) {
 | 
			
		||||
        switch (intno) {
 | 
			
		||||
        case TT_IVEC:
 | 
			
		||||
            change_pstate(PS_PEF | PS_PRIV | PS_IG);
 | 
			
		||||
            break;
 | 
			
		||||
        case TT_TFAULT:
 | 
			
		||||
        case TT_TMISS:
 | 
			
		||||
        case TT_DFAULT:
 | 
			
		||||
        case TT_DMISS:
 | 
			
		||||
        case TT_DPROT:
 | 
			
		||||
            change_pstate(PS_PEF | PS_PRIV | PS_MG);
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            change_pstate(PS_PEF | PS_PRIV | PS_AG);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (intno == TT_CLRWIN)
 | 
			
		||||
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
 | 
			
		||||
    else if ((intno & 0x1c0) == TT_SPILL)
 | 
			
		||||
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
 | 
			
		||||
    else if ((intno & 0x1c0) == TT_FILL)
 | 
			
		||||
        cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
 | 
			
		||||
    env->tbr &= ~0x7fffULL;
 | 
			
		||||
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
 | 
			
		||||
    env->pc = env->tbr;
 | 
			
		||||
    env->npc = env->pc + 4;
 | 
			
		||||
    env->exception_index = 0;
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
#ifdef DEBUG_PCALL
 | 
			
		||||
static const char * const excp_names[0x80] = {
 | 
			
		||||
    [TT_TFAULT] = "Instruction Access Fault",
 | 
			
		||||
    [TT_ILL_INSN] = "Illegal Instruction",
 | 
			
		||||
    [TT_PRIV_INSN] = "Privileged Instruction",
 | 
			
		||||
    [TT_NFPU_INSN] = "FPU Disabled",
 | 
			
		||||
    [TT_WIN_OVF] = "Window Overflow",
 | 
			
		||||
    [TT_WIN_UNF] = "Window Underflow",
 | 
			
		||||
    [TT_UNALIGNED] = "Unaligned Memory Access",
 | 
			
		||||
    [TT_FP_EXCP] = "FPU Exception",
 | 
			
		||||
    [TT_DFAULT] = "Data Access Fault",
 | 
			
		||||
    [TT_TOVF] = "Tag Overflow",
 | 
			
		||||
    [TT_EXTINT | 0x1] = "External Interrupt 1",
 | 
			
		||||
    [TT_EXTINT | 0x2] = "External Interrupt 2",
 | 
			
		||||
    [TT_EXTINT | 0x3] = "External Interrupt 3",
 | 
			
		||||
    [TT_EXTINT | 0x4] = "External Interrupt 4",
 | 
			
		||||
    [TT_EXTINT | 0x5] = "External Interrupt 5",
 | 
			
		||||
    [TT_EXTINT | 0x6] = "External Interrupt 6",
 | 
			
		||||
    [TT_EXTINT | 0x7] = "External Interrupt 7",
 | 
			
		||||
    [TT_EXTINT | 0x8] = "External Interrupt 8",
 | 
			
		||||
    [TT_EXTINT | 0x9] = "External Interrupt 9",
 | 
			
		||||
    [TT_EXTINT | 0xa] = "External Interrupt 10",
 | 
			
		||||
    [TT_EXTINT | 0xb] = "External Interrupt 11",
 | 
			
		||||
    [TT_EXTINT | 0xc] = "External Interrupt 12",
 | 
			
		||||
    [TT_EXTINT | 0xd] = "External Interrupt 13",
 | 
			
		||||
    [TT_EXTINT | 0xe] = "External Interrupt 14",
 | 
			
		||||
    [TT_EXTINT | 0xf] = "External Interrupt 15",
 | 
			
		||||
    [TT_TOVF] = "Tag Overflow",
 | 
			
		||||
    [TT_CODE_ACCESS] = "Instruction Access Error",
 | 
			
		||||
    [TT_DATA_ACCESS] = "Data Access Error",
 | 
			
		||||
    [TT_DIV_ZERO] = "Division By Zero",
 | 
			
		||||
    [TT_NCP_INSN] = "Coprocessor Disabled",
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void do_interrupt(CPUState *env)
 | 
			
		||||
{
 | 
			
		||||
    int cwp, intno = env->exception_index;
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_PCALL
 | 
			
		||||
    if (loglevel & CPU_LOG_INT) {
 | 
			
		||||
        static int count;
 | 
			
		||||
        const char *name;
 | 
			
		||||
 | 
			
		||||
        if (intno < 0 || intno >= 0x100)
 | 
			
		||||
            name = "Unknown";
 | 
			
		||||
        else if (intno >= 0x80)
 | 
			
		||||
            name = "Trap Instruction";
 | 
			
		||||
        else {
 | 
			
		||||
            name = excp_names[intno];
 | 
			
		||||
            if (!name)
 | 
			
		||||
                name = "Unknown";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fprintf(logfile, "%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
 | 
			
		||||
                count, name, intno,
 | 
			
		||||
                env->pc,
 | 
			
		||||
                env->npc, env->regwptr[6]);
 | 
			
		||||
        cpu_dump_state(env, logfile, fprintf, 0);
 | 
			
		||||
#if 0
 | 
			
		||||
        {
 | 
			
		||||
            int i;
 | 
			
		||||
            uint8_t *ptr;
 | 
			
		||||
 | 
			
		||||
            fprintf(logfile, "       code=");
 | 
			
		||||
            ptr = (uint8_t *)env->pc;
 | 
			
		||||
            for(i = 0; i < 16; i++) {
 | 
			
		||||
                fprintf(logfile, " %02x", ldub(ptr + i));
 | 
			
		||||
            }
 | 
			
		||||
            fprintf(logfile, "\n");
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        count++;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
#if !defined(CONFIG_USER_ONLY)
 | 
			
		||||
    if (env->psret == 0) {
 | 
			
		||||
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
 | 
			
		||||
                  env->exception_index);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    env->psret = 0;
 | 
			
		||||
    cwp = cpu_cwp_dec(env, env->cwp - 1);
 | 
			
		||||
    cpu_set_cwp(env, cwp);
 | 
			
		||||
    env->regwptr[9] = env->pc;
 | 
			
		||||
    env->regwptr[10] = env->npc;
 | 
			
		||||
    env->psrps = env->psrs;
 | 
			
		||||
    env->psrs = 1;
 | 
			
		||||
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
 | 
			
		||||
    env->pc = env->tbr;
 | 
			
		||||
    env->npc = env->pc + 4;
 | 
			
		||||
    env->exception_index = 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void memcpy32(target_ulong *dst, const target_ulong *src)
 | 
			
		||||
{
 | 
			
		||||
    dst[0] = src[0];
 | 
			
		||||
    dst[1] = src[1];
 | 
			
		||||
    dst[2] = src[2];
 | 
			
		||||
    dst[3] = src[3];
 | 
			
		||||
    dst[4] = src[4];
 | 
			
		||||
    dst[5] = src[5];
 | 
			
		||||
    dst[6] = src[6];
 | 
			
		||||
    dst[7] = src[7];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cpu_reset(CPUSPARCState *env)
 | 
			
		||||
{
 | 
			
		||||
    tlb_flush(env, 1);
 | 
			
		||||
 | 
			
		||||
@ -179,12 +179,3 @@ VIS_CMPHELPER(cmpne);
 | 
			
		||||
#undef F_HELPER_SDQ_0_0
 | 
			
		||||
#undef VIS_HELPER
 | 
			
		||||
#undef VIS_CMPHELPER
 | 
			
		||||
 | 
			
		||||
void cpu_lock(void);
 | 
			
		||||
void cpu_unlock(void);
 | 
			
		||||
void cpu_loop_exit(void);
 | 
			
		||||
void set_cwp(int new_cwp);
 | 
			
		||||
void change_pstate(uint64_t new_pstate);
 | 
			
		||||
void memcpy32(target_ulong *dst, const target_ulong *src);
 | 
			
		||||
target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev);
 | 
			
		||||
void dump_mmu(CPUState *env);
 | 
			
		||||
 | 
			
		||||
@ -68,6 +68,11 @@ void helper_trapcc(target_ulong nb_trap, target_ulong do_trap)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void set_cwp(int new_cwp)
 | 
			
		||||
{
 | 
			
		||||
    cpu_set_cwp(env, new_cwp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void helper_check_align(target_ulong addr, uint32_t align)
 | 
			
		||||
{
 | 
			
		||||
    if (addr & align) {
 | 
			
		||||
@ -2668,7 +2673,7 @@ static inline uint64_t *get_gregset(uint64_t pstate)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void change_pstate(uint64_t new_pstate)
 | 
			
		||||
static inline void change_pstate(uint64_t new_pstate)
 | 
			
		||||
{
 | 
			
		||||
    uint64_t pstate_regs, new_pstate_regs;
 | 
			
		||||
    uint64_t *src, *dst;
 | 
			
		||||
@ -2716,29 +2721,241 @@ void helper_retry(void)
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void cpu_set_cwp(CPUState *env1, int new_cwp)
 | 
			
		||||
{
 | 
			
		||||
    /* put the modified wrap registers at their proper location */
 | 
			
		||||
    if (env1->cwp == env1->nwindows - 1)
 | 
			
		||||
        memcpy32(env1->regbase, env1->regbase + env1->nwindows * 16);
 | 
			
		||||
    env1->cwp = new_cwp;
 | 
			
		||||
    /* put the wrap registers at their temporary location */
 | 
			
		||||
    if (new_cwp == env1->nwindows - 1)
 | 
			
		||||
        memcpy32(env1->regbase + env1->nwindows * 16, env1->regbase);
 | 
			
		||||
    env1->regwptr = env1->regbase + (new_cwp * 16);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_cwp(int new_cwp)
 | 
			
		||||
{
 | 
			
		||||
    cpu_set_cwp(env, new_cwp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void helper_flush(target_ulong addr)
 | 
			
		||||
{
 | 
			
		||||
    addr &= ~7;
 | 
			
		||||
    tb_invalidate_page_range(addr, addr + 8);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef TARGET_SPARC64
 | 
			
		||||
#ifdef DEBUG_PCALL
 | 
			
		||||
static const char * const excp_names[0x80] = {
 | 
			
		||||
    [TT_TFAULT] = "Instruction Access Fault",
 | 
			
		||||
    [TT_TMISS] = "Instruction Access MMU Miss",
 | 
			
		||||
    [TT_CODE_ACCESS] = "Instruction Access Error",
 | 
			
		||||
    [TT_ILL_INSN] = "Illegal Instruction",
 | 
			
		||||
    [TT_PRIV_INSN] = "Privileged Instruction",
 | 
			
		||||
    [TT_NFPU_INSN] = "FPU Disabled",
 | 
			
		||||
    [TT_FP_EXCP] = "FPU Exception",
 | 
			
		||||
    [TT_TOVF] = "Tag Overflow",
 | 
			
		||||
    [TT_CLRWIN] = "Clean Windows",
 | 
			
		||||
    [TT_DIV_ZERO] = "Division By Zero",
 | 
			
		||||
    [TT_DFAULT] = "Data Access Fault",
 | 
			
		||||
    [TT_DMISS] = "Data Access MMU Miss",
 | 
			
		||||
    [TT_DATA_ACCESS] = "Data Access Error",
 | 
			
		||||
    [TT_DPROT] = "Data Protection Error",
 | 
			
		||||
    [TT_UNALIGNED] = "Unaligned Memory Access",
 | 
			
		||||
    [TT_PRIV_ACT] = "Privileged Action",
 | 
			
		||||
    [TT_EXTINT | 0x1] = "External Interrupt 1",
 | 
			
		||||
    [TT_EXTINT | 0x2] = "External Interrupt 2",
 | 
			
		||||
    [TT_EXTINT | 0x3] = "External Interrupt 3",
 | 
			
		||||
    [TT_EXTINT | 0x4] = "External Interrupt 4",
 | 
			
		||||
    [TT_EXTINT | 0x5] = "External Interrupt 5",
 | 
			
		||||
    [TT_EXTINT | 0x6] = "External Interrupt 6",
 | 
			
		||||
    [TT_EXTINT | 0x7] = "External Interrupt 7",
 | 
			
		||||
    [TT_EXTINT | 0x8] = "External Interrupt 8",
 | 
			
		||||
    [TT_EXTINT | 0x9] = "External Interrupt 9",
 | 
			
		||||
    [TT_EXTINT | 0xa] = "External Interrupt 10",
 | 
			
		||||
    [TT_EXTINT | 0xb] = "External Interrupt 11",
 | 
			
		||||
    [TT_EXTINT | 0xc] = "External Interrupt 12",
 | 
			
		||||
    [TT_EXTINT | 0xd] = "External Interrupt 13",
 | 
			
		||||
    [TT_EXTINT | 0xe] = "External Interrupt 14",
 | 
			
		||||
    [TT_EXTINT | 0xf] = "External Interrupt 15",
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void do_interrupt(CPUState *env)
 | 
			
		||||
{
 | 
			
		||||
    int intno = env->exception_index;
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_PCALL
 | 
			
		||||
    if (loglevel & CPU_LOG_INT) {
 | 
			
		||||
        static int count;
 | 
			
		||||
        const char *name;
 | 
			
		||||
 | 
			
		||||
        if (intno < 0 || intno >= 0x180)
 | 
			
		||||
            name = "Unknown";
 | 
			
		||||
        else if (intno >= 0x100)
 | 
			
		||||
            name = "Trap Instruction";
 | 
			
		||||
        else if (intno >= 0xc0)
 | 
			
		||||
            name = "Window Fill";
 | 
			
		||||
        else if (intno >= 0x80)
 | 
			
		||||
            name = "Window Spill";
 | 
			
		||||
        else {
 | 
			
		||||
            name = excp_names[intno];
 | 
			
		||||
            if (!name)
 | 
			
		||||
                name = "Unknown";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fprintf(logfile, "%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
 | 
			
		||||
                " SP=%016" PRIx64 "\n",
 | 
			
		||||
                count, name, intno,
 | 
			
		||||
                env->pc,
 | 
			
		||||
                env->npc, env->regwptr[6]);
 | 
			
		||||
        cpu_dump_state(env, logfile, fprintf, 0);
 | 
			
		||||
#if 0
 | 
			
		||||
        {
 | 
			
		||||
            int i;
 | 
			
		||||
            uint8_t *ptr;
 | 
			
		||||
 | 
			
		||||
            fprintf(logfile, "       code=");
 | 
			
		||||
            ptr = (uint8_t *)env->pc;
 | 
			
		||||
            for(i = 0; i < 16; i++) {
 | 
			
		||||
                fprintf(logfile, " %02x", ldub(ptr + i));
 | 
			
		||||
            }
 | 
			
		||||
            fprintf(logfile, "\n");
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        count++;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
#if !defined(CONFIG_USER_ONLY)
 | 
			
		||||
    if (env->tl >= env->maxtl) {
 | 
			
		||||
        cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
 | 
			
		||||
                  " Error state", env->exception_index, env->tl, env->maxtl);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    if (env->tl < env->maxtl - 1) {
 | 
			
		||||
        env->tl++;
 | 
			
		||||
    } else {
 | 
			
		||||
        env->pstate |= PS_RED;
 | 
			
		||||
        if (env->tl < env->maxtl)
 | 
			
		||||
            env->tl++;
 | 
			
		||||
    }
 | 
			
		||||
    env->tsptr = &env->ts[env->tl & MAXTL_MASK];
 | 
			
		||||
    env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
 | 
			
		||||
        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
 | 
			
		||||
        GET_CWP64(env);
 | 
			
		||||
    env->tsptr->tpc = env->pc;
 | 
			
		||||
    env->tsptr->tnpc = env->npc;
 | 
			
		||||
    env->tsptr->tt = intno;
 | 
			
		||||
    if (!(env->def->features & CPU_FEATURE_GL)) {
 | 
			
		||||
        switch (intno) {
 | 
			
		||||
        case TT_IVEC:
 | 
			
		||||
            change_pstate(PS_PEF | PS_PRIV | PS_IG);
 | 
			
		||||
            break;
 | 
			
		||||
        case TT_TFAULT:
 | 
			
		||||
        case TT_TMISS:
 | 
			
		||||
        case TT_DFAULT:
 | 
			
		||||
        case TT_DMISS:
 | 
			
		||||
        case TT_DPROT:
 | 
			
		||||
            change_pstate(PS_PEF | PS_PRIV | PS_MG);
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            change_pstate(PS_PEF | PS_PRIV | PS_AG);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (intno == TT_CLRWIN)
 | 
			
		||||
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
 | 
			
		||||
    else if ((intno & 0x1c0) == TT_SPILL)
 | 
			
		||||
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
 | 
			
		||||
    else if ((intno & 0x1c0) == TT_FILL)
 | 
			
		||||
        cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
 | 
			
		||||
    env->tbr &= ~0x7fffULL;
 | 
			
		||||
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
 | 
			
		||||
    env->pc = env->tbr;
 | 
			
		||||
    env->npc = env->pc + 4;
 | 
			
		||||
    env->exception_index = 0;
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
#ifdef DEBUG_PCALL
 | 
			
		||||
static const char * const excp_names[0x80] = {
 | 
			
		||||
    [TT_TFAULT] = "Instruction Access Fault",
 | 
			
		||||
    [TT_ILL_INSN] = "Illegal Instruction",
 | 
			
		||||
    [TT_PRIV_INSN] = "Privileged Instruction",
 | 
			
		||||
    [TT_NFPU_INSN] = "FPU Disabled",
 | 
			
		||||
    [TT_WIN_OVF] = "Window Overflow",
 | 
			
		||||
    [TT_WIN_UNF] = "Window Underflow",
 | 
			
		||||
    [TT_UNALIGNED] = "Unaligned Memory Access",
 | 
			
		||||
    [TT_FP_EXCP] = "FPU Exception",
 | 
			
		||||
    [TT_DFAULT] = "Data Access Fault",
 | 
			
		||||
    [TT_TOVF] = "Tag Overflow",
 | 
			
		||||
    [TT_EXTINT | 0x1] = "External Interrupt 1",
 | 
			
		||||
    [TT_EXTINT | 0x2] = "External Interrupt 2",
 | 
			
		||||
    [TT_EXTINT | 0x3] = "External Interrupt 3",
 | 
			
		||||
    [TT_EXTINT | 0x4] = "External Interrupt 4",
 | 
			
		||||
    [TT_EXTINT | 0x5] = "External Interrupt 5",
 | 
			
		||||
    [TT_EXTINT | 0x6] = "External Interrupt 6",
 | 
			
		||||
    [TT_EXTINT | 0x7] = "External Interrupt 7",
 | 
			
		||||
    [TT_EXTINT | 0x8] = "External Interrupt 8",
 | 
			
		||||
    [TT_EXTINT | 0x9] = "External Interrupt 9",
 | 
			
		||||
    [TT_EXTINT | 0xa] = "External Interrupt 10",
 | 
			
		||||
    [TT_EXTINT | 0xb] = "External Interrupt 11",
 | 
			
		||||
    [TT_EXTINT | 0xc] = "External Interrupt 12",
 | 
			
		||||
    [TT_EXTINT | 0xd] = "External Interrupt 13",
 | 
			
		||||
    [TT_EXTINT | 0xe] = "External Interrupt 14",
 | 
			
		||||
    [TT_EXTINT | 0xf] = "External Interrupt 15",
 | 
			
		||||
    [TT_TOVF] = "Tag Overflow",
 | 
			
		||||
    [TT_CODE_ACCESS] = "Instruction Access Error",
 | 
			
		||||
    [TT_DATA_ACCESS] = "Data Access Error",
 | 
			
		||||
    [TT_DIV_ZERO] = "Division By Zero",
 | 
			
		||||
    [TT_NCP_INSN] = "Coprocessor Disabled",
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void do_interrupt(CPUState *env)
 | 
			
		||||
{
 | 
			
		||||
    int cwp, intno = env->exception_index;
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_PCALL
 | 
			
		||||
    if (loglevel & CPU_LOG_INT) {
 | 
			
		||||
        static int count;
 | 
			
		||||
        const char *name;
 | 
			
		||||
 | 
			
		||||
        if (intno < 0 || intno >= 0x100)
 | 
			
		||||
            name = "Unknown";
 | 
			
		||||
        else if (intno >= 0x80)
 | 
			
		||||
            name = "Trap Instruction";
 | 
			
		||||
        else {
 | 
			
		||||
            name = excp_names[intno];
 | 
			
		||||
            if (!name)
 | 
			
		||||
                name = "Unknown";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fprintf(logfile, "%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
 | 
			
		||||
                count, name, intno,
 | 
			
		||||
                env->pc,
 | 
			
		||||
                env->npc, env->regwptr[6]);
 | 
			
		||||
        cpu_dump_state(env, logfile, fprintf, 0);
 | 
			
		||||
#if 0
 | 
			
		||||
        {
 | 
			
		||||
            int i;
 | 
			
		||||
            uint8_t *ptr;
 | 
			
		||||
 | 
			
		||||
            fprintf(logfile, "       code=");
 | 
			
		||||
            ptr = (uint8_t *)env->pc;
 | 
			
		||||
            for(i = 0; i < 16; i++) {
 | 
			
		||||
                fprintf(logfile, " %02x", ldub(ptr + i));
 | 
			
		||||
            }
 | 
			
		||||
            fprintf(logfile, "\n");
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        count++;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
#if !defined(CONFIG_USER_ONLY)
 | 
			
		||||
    if (env->psret == 0) {
 | 
			
		||||
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
 | 
			
		||||
                  env->exception_index);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    env->psret = 0;
 | 
			
		||||
    cwp = cpu_cwp_dec(env, env->cwp - 1);
 | 
			
		||||
    cpu_set_cwp(env, cwp);
 | 
			
		||||
    env->regwptr[9] = env->pc;
 | 
			
		||||
    env->regwptr[10] = env->npc;
 | 
			
		||||
    env->psrps = env->psrs;
 | 
			
		||||
    env->psrs = 1;
 | 
			
		||||
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
 | 
			
		||||
    env->pc = env->tbr;
 | 
			
		||||
    env->npc = env->pc + 4;
 | 
			
		||||
    env->exception_index = 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(CONFIG_USER_ONLY)
 | 
			
		||||
 | 
			
		||||
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user