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
This commit is contained in:
blueswir1 2008-05-27 17:35:30 +00:00
parent 8d96d20941
commit f2bc7e7fa1
5 changed files with 235 additions and 245 deletions

View file

@ -32,6 +32,7 @@
//#define DEBUG_MMU
//#define DEBUG_FEATURES
//#define DEBUG_PCALL
typedef struct sparc_def_t sparc_def_t;
@ -651,6 +652,220 @@ 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[0x50] = {
[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 || (intno > 0x4f && intno < 0x80))
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 == MAXTL) {
cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state",
env->exception_index);
return;
}
#endif
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;
change_pstate(PS_PEF | PS_PRIV | PS_AG);
if (intno == TT_CLRWIN)
cpu_set_cwp(env, (env->cwp - 1) & (NWINDOWS - 1));
else if ((intno & 0x1c0) == TT_SPILL)
cpu_set_cwp(env, (env->cwp - env->cansave - 2) & (NWINDOWS - 1));
else if ((intno & 0x1c0) == TT_FILL)
cpu_set_cwp(env, (env->cwp + 1) & (NWINDOWS - 1));
env->tbr &= ~0x7fffULL;
env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
if (env->tl < MAXTL - 1) {
env->tl++;
} else {
env->pstate |= PS_RED;
if (env->tl != MAXTL)
env->tl++;
}
env->tsptr = &env->ts[env->tl];
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 = (env->cwp - 1) & (NWINDOWS - 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];
@ -663,12 +878,6 @@ void memcpy32(target_ulong *dst, const target_ulong *src)
dst[7] = src[7];
}
void helper_flush(target_ulong addr)
{
addr &= ~7;
tb_invalidate_page_range(addr, addr + 8);
}
void cpu_reset(CPUSPARCState *env)
{
tlb_flush(env, 1);