-#include "exec.h"
-#include "host-utils.h"
+#include "cpu.h"
+#include "dyngen-exec.h"
#include "helper.h"
-#include "sysemu.h"
+
+#if !defined(CONFIG_USER_ONLY)
+#include "softmmu_exec.h"
+#endif
//#define DEBUG_MMU
//#define DEBUG_MXCC
//#define DEBUG_UNALIGNED
//#define DEBUG_UNASSIGNED
//#define DEBUG_ASI
-//#define DEBUG_PCALL
//#define DEBUG_PSTATE
//#define DEBUG_CACHE_CONTROL
#define CACHE_CTRL_FD (1 << 22) /* Flush Data cache (Write only) */
#define CACHE_CTRL_DS (1 << 23) /* Data cache snoop enable */
-#if defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
+#if !defined(CONFIG_USER_ONLY)
+static void do_unassigned_access(target_phys_addr_t addr, int is_write,
+ int is_exec, int is_asi, int size);
+#else
+#ifdef TARGET_SPARC64
static void do_unassigned_access(target_ulong addr, int is_write, int is_exec,
- int is_asi, int size);
+ int is_asi, int size);
+#endif
#endif
#if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
*/
switch (asi) {
case 0x04 ... 0x11:
- case 0x18 ... 0x19:
+ case 0x16 ... 0x19:
+ case 0x1E ... 0x1F:
case 0x24 ... 0x2C:
case 0x70 ... 0x73:
case 0x78 ... 0x79:
static void raise_exception(int tt)
{
env->exception_index = tt;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
void HELPER(raise_exception)(int tt)
raise_exception(tt);
}
-void helper_shutdown(void)
-{
-#if !defined(CONFIG_USER_ONLY)
- qemu_system_shutdown_request();
-#endif
-}
-
void helper_check_align(target_ulong addr, uint32_t align)
{
if (addr & align) {
uint16_t w[4];
int16_t sw[4];
uint32_t l[2];
+ uint64_t ll;
float64 d;
} vis64;
VIS_HELPER(helper_fpsub, FSUB)
#define VIS_CMPHELPER(name, F) \
- void name##16(void) \
+ uint64_t name##16(void) \
{ \
vis64 s, d; \
\
s.d = DT0; \
d.d = DT1; \
\
- d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0))? 1: 0; \
- d.VIS_W64(0) |= F(d.VIS_W64(1), s.VIS_W64(1))? 2: 0; \
- d.VIS_W64(0) |= F(d.VIS_W64(2), s.VIS_W64(2))? 4: 0; \
- d.VIS_W64(0) |= F(d.VIS_W64(3), s.VIS_W64(3))? 8: 0; \
+ d.VIS_W64(0) = F(s.VIS_W64(0), d.VIS_W64(0)) ? 1 : 0; \
+ d.VIS_W64(0) |= F(s.VIS_W64(1), d.VIS_W64(1)) ? 2 : 0; \
+ d.VIS_W64(0) |= F(s.VIS_W64(2), d.VIS_W64(2)) ? 4 : 0; \
+ d.VIS_W64(0) |= F(s.VIS_W64(3), d.VIS_W64(3)) ? 8 : 0; \
+ d.VIS_W64(1) = d.VIS_W64(2) = d.VIS_W64(3) = 0; \
\
- DT0 = d.d; \
+ return d.ll; \
} \
\
- void name##32(void) \
+ uint64_t name##32(void) \
{ \
vis64 s, d; \
\
s.d = DT0; \
d.d = DT1; \
\
- d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0))? 1: 0; \
- d.VIS_L64(0) |= F(d.VIS_L64(1), s.VIS_L64(1))? 2: 0; \
+ d.VIS_L64(0) = F(s.VIS_L64(0), d.VIS_L64(0)) ? 1 : 0; \
+ d.VIS_L64(0) |= F(s.VIS_L64(1), d.VIS_L64(1)) ? 2 : 0; \
+ d.VIS_L64(1) = 0; \
\
- DT0 = d.d; \
+ return d.ll; \
}
#define FCMPGT(a, b) ((a) > (b))
case 0x31: // Turbosparc RAM snoop
case 0x32: // Turbosparc page table descriptor diagnostic
case 0x39: /* data cache diagnostic register */
- case 0x4c: /* SuperSPARC MMU Breakpoint Action register */
ret = 0;
break;
case 0x38: /* SuperSPARC MMU Breakpoint Control Registers */
ret);
}
break;
+ case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
+ ret = env->mmubpctrv;
+ break;
+ case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
+ ret = env->mmubpctrc;
+ break;
+ case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
+ ret = env->mmubpctrs;
+ break;
+ case 0x4c: /* SuperSPARC MMU Breakpoint Action */
+ ret = env->mmubpaction;
+ break;
case 8: /* User code access, XXX */
default:
do_unassigned_access(addr, 0, 0, asi, size);
// descriptor diagnostic
case 0x36: /* I-cache flash clear */
case 0x37: /* D-cache flash clear */
- case 0x4c: /* breakpoint action */
break;
case 0x38: /* SuperSPARC MMU Breakpoint Control Registers*/
{
env->mmuregs[reg]);
}
break;
+ case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
+ env->mmubpctrv = val & 0xffffffff;
+ break;
+ case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
+ env->mmubpctrc = val & 0x3;
+ break;
+ case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
+ env->mmubpctrs = val & 0x3;
+ break;
+ case 0x4c: /* SuperSPARC MMU Breakpoint Action */
+ env->mmubpaction = val & 0x1fff;
+ break;
case 8: /* User code access, XXX */
case 9: /* Supervisor code access, XXX */
default:
helper_check_align(addr, size - 1);
addr = asi_address_mask(env, asi, addr);
- switch (asi) {
- case 0x82: // Primary no-fault
- case 0x8a: // Primary no-fault LE
- case 0x83: // Secondary no-fault
- case 0x8b: // Secondary no-fault LE
- {
- /* secondary space access has lowest asi bit equal to 1 */
- int access_mmu_idx = ( asi & 1 ) ? MMU_KERNEL_IDX
- : MMU_KERNEL_SECONDARY_IDX;
+ /* process nonfaulting loads first */
+ if ((asi & 0xf6) == 0x82) {
+ int mmu_idx;
- if (cpu_get_phys_page_nofault(env, addr, access_mmu_idx) == -1ULL) {
+ /* secondary space access has lowest asi bit equal to 1 */
+ if (env->pstate & PS_PRIV) {
+ mmu_idx = (asi & 1) ? MMU_KERNEL_SECONDARY_IDX : MMU_KERNEL_IDX;
+ } else {
+ mmu_idx = (asi & 1) ? MMU_USER_SECONDARY_IDX : MMU_USER_IDX;
+ }
+
+ if (cpu_get_phys_page_nofault(env, addr, mmu_idx) == -1ULL) {
#ifdef DEBUG_ASI
- dump_asi("read ", last_addr, asi, size, ret);
+ dump_asi("read ", last_addr, asi, size, ret);
#endif
- return 0;
- }
+ /* env->exception_index is set in get_physical_address_data(). */
+ raise_exception(env->exception_index);
}
- // Fall through
+
+ /* convert nonfaulting load ASIs to normal load ASIs */
+ asi &= ~0x02;
+ }
+
+ switch (asi) {
case 0x10: // As if user primary
case 0x11: // As if user secondary
case 0x18: // As if user primary LE
case 0x1d: // Bypass, non-cacheable LE
case 0x88: // Primary LE
case 0x89: // Secondary LE
- case 0x8a: // Primary no-fault LE
- case 0x8b: // Secondary no-fault LE
switch(size) {
case 2:
ret = bswap16(ret);
void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
{
unsigned int i;
- target_ulong val;
+ CPU_DoubleU u;
helper_check_align(addr, 3);
addr = asi_address_mask(env, asi, addr);
switch (asi) {
- case 0xf0: // Block load primary
- case 0xf1: // Block load secondary
- case 0xf8: // Block load primary LE
- case 0xf9: // Block load secondary LE
+ case 0xf0: /* UA2007/JPS1 Block load primary */
+ case 0xf1: /* UA2007/JPS1 Block load secondary */
+ case 0xf8: /* UA2007/JPS1 Block load primary LE */
+ case 0xf9: /* UA2007/JPS1 Block load secondary LE */
if (rd & 7) {
raise_exception(TT_ILL_INSN);
return;
}
return;
- case 0x70: // Block load primary, user privilege
- case 0x71: // Block load secondary, user privilege
+ case 0x16: /* UA2007 Block load primary, user privilege */
+ case 0x17: /* UA2007 Block load secondary, user privilege */
+ case 0x1e: /* UA2007 Block load primary LE, user privilege */
+ case 0x1f: /* UA2007 Block load secondary LE, user privilege */
+ case 0x70: /* JPS1 Block load primary, user privilege */
+ case 0x71: /* JPS1 Block load secondary, user privilege */
+ case 0x78: /* JPS1 Block load primary LE, user privilege */
+ case 0x79: /* JPS1 Block load secondary LE, user privilege */
if (rd & 7) {
raise_exception(TT_ILL_INSN);
return;
}
helper_check_align(addr, 0x3f);
for (i = 0; i < 16; i++) {
- *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x1f, 4,
+ *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x19, 4,
0);
addr += 4;
}
break;
}
- val = helper_ld_asi(addr, asi, size, 0);
switch(size) {
default:
case 4:
- *((uint32_t *)&env->fpr[rd]) = val;
+ *((uint32_t *)&env->fpr[rd]) = helper_ld_asi(addr, asi, size, 0);
break;
case 8:
- *((int64_t *)&DT0) = val;
+ u.ll = helper_ld_asi(addr, asi, size, 0);
+ *((uint32_t *)&env->fpr[rd++]) = u.l.upper;
+ *((uint32_t *)&env->fpr[rd++]) = u.l.lower;
break;
case 16:
- // XXX
+ u.ll = helper_ld_asi(addr, asi, 8, 0);
+ *((uint32_t *)&env->fpr[rd++]) = u.l.upper;
+ *((uint32_t *)&env->fpr[rd++]) = u.l.lower;
+ u.ll = helper_ld_asi(addr + 8, asi, 8, 0);
+ *((uint32_t *)&env->fpr[rd++]) = u.l.upper;
+ *((uint32_t *)&env->fpr[rd++]) = u.l.lower;
break;
}
}
{
unsigned int i;
target_ulong val = 0;
+ CPU_DoubleU u;
helper_check_align(addr, 3);
addr = asi_address_mask(env, asi, addr);
switch (asi) {
- case 0xe0: // UA2007 Block commit store primary (cache flush)
- case 0xe1: // UA2007 Block commit store secondary (cache flush)
- case 0xf0: // Block store primary
- case 0xf1: // Block store secondary
- case 0xf8: // Block store primary LE
- case 0xf9: // Block store secondary LE
+ case 0xe0: /* UA2007/JPS1 Block commit store primary (cache flush) */
+ case 0xe1: /* UA2007/JPS1 Block commit store secondary (cache flush) */
+ case 0xf0: /* UA2007/JPS1 Block store primary */
+ case 0xf1: /* UA2007/JPS1 Block store secondary */
+ case 0xf8: /* UA2007/JPS1 Block store primary LE */
+ case 0xf9: /* UA2007/JPS1 Block store secondary LE */
if (rd & 7) {
raise_exception(TT_ILL_INSN);
return;
}
return;
- case 0x70: // Block store primary, user privilege
- case 0x71: // Block store secondary, user privilege
+ case 0x16: /* UA2007 Block load primary, user privilege */
+ case 0x17: /* UA2007 Block load secondary, user privilege */
+ case 0x1e: /* UA2007 Block load primary LE, user privilege */
+ case 0x1f: /* UA2007 Block load secondary LE, user privilege */
+ case 0x70: /* JPS1 Block store primary, user privilege */
+ case 0x71: /* JPS1 Block store secondary, user privilege */
+ case 0x78: /* JPS1 Block load primary LE, user privilege */
+ case 0x79: /* JPS1 Block load secondary LE, user privilege */
if (rd & 7) {
raise_exception(TT_ILL_INSN);
return;
helper_check_align(addr, 0x3f);
for (i = 0; i < 16; i++) {
val = *(uint32_t *)&env->fpr[rd++];
- helper_st_asi(addr, val, asi & 0x1f, 4);
+ helper_st_asi(addr, val, asi & 0x19, 4);
addr += 4;
}
switch(size) {
default:
case 4:
- val = *((uint32_t *)&env->fpr[rd]);
+ helper_st_asi(addr, *(uint32_t *)&env->fpr[rd], asi, size);
break;
case 8:
- val = *((int64_t *)&DT0);
+ u.l.upper = *(uint32_t *)&env->fpr[rd++];
+ u.l.lower = *(uint32_t *)&env->fpr[rd++];
+ helper_st_asi(addr, u.ll, asi, size);
break;
case 16:
- // XXX
+ u.l.upper = *(uint32_t *)&env->fpr[rd++];
+ u.l.lower = *(uint32_t *)&env->fpr[rd++];
+ helper_st_asi(addr, u.ll, asi, 8);
+ u.l.upper = *(uint32_t *)&env->fpr[rd++];
+ u.l.lower = *(uint32_t *)&env->fpr[rd++];
+ helper_st_asi(addr + 8, u.ll, asi, 8);
break;
}
- helper_st_asi(addr, val, asi, size);
}
target_ulong helper_cas_asi(target_ulong addr, target_ulong val1,
void helper_debug(void)
{
env->exception_index = EXCP_DEBUG;
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
#ifndef TARGET_SPARC64
static void put_ccr(target_ulong val)
{
- target_ulong tmp = val;
-
- env->xcc = (tmp >> 4) << 20;
- env->psr = (tmp & 0xf) << 20;
+ env->xcc = (val >> 4) << 20;
+ env->psr = (val & 0xf) << 20;
CC_OP = CC_OP_FLAGS;
}
return tmp & ~7ULL;
}
-target_ulong helper_popc(target_ulong val)
-{
- return ctpop64(val);
-}
-
static inline uint64_t *get_gregset(uint32_t pstate)
{
switch (pstate) {
#endif
}
+void cpu_change_pstate(CPUState *env1, uint32_t new_pstate)
+{
+ CPUState *saved_env;
+
+ saved_env = env;
+ env = env1;
+ change_pstate(new_pstate);
+ env = saved_env;
+}
+
void helper_wrpil(target_ulong new_pil)
{
#if !defined(CONFIG_USER_ONLY)
}
#endif
-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
-
-trap_state* cpu_tsptr(CPUState* env)
-{
- return &env->ts[env->tl & MAXTL_MASK];
-}
-
-void do_interrupt(CPUState *env)
-{
- int intno = env->exception_index;
- trap_state* tsptr;
-
-#ifdef DEBUG_PCALL
- if (qemu_loglevel_mask(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";
- }
-
- qemu_log("%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
- " SP=%016" PRIx64 "\n",
- count, name, intno,
- env->pc,
- env->npc, env->regwptr[6]);
- log_cpu_state(env, 0);
-#if 0
- {
- int i;
- uint8_t *ptr;
-
- qemu_log(" code=");
- ptr = (uint8_t *)env->pc;
- for(i = 0; i < 16; i++) {
- qemu_log(" %02x", ldub(ptr + i));
- }
- qemu_log("\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++;
- }
- tsptr = cpu_tsptr(env);
-
- tsptr->tstate = (get_ccr() << 32) |
- ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
- get_cwp64();
- tsptr->tpc = env->pc;
- tsptr->tnpc = env->npc;
- tsptr->tt = intno;
-
- switch (intno) {
- case TT_IVEC:
- change_pstate(PS_PEF | PS_PRIV | PS_IG);
- break;
- case TT_TFAULT:
- case TT_DFAULT:
- case TT_TMISS ... TT_TMISS + 3:
- case TT_DMISS ... TT_DMISS + 3:
- case TT_DPROT ... TT_DPROT + 3:
- change_pstate(PS_PEF | PS_PRIV | PS_MG);
- break;
- default:
- change_pstate(PS_PEF | PS_PRIV | PS_AG);
- break;
- }
-
- if (intno == TT_CLRWIN) {
- set_cwp(cwp_dec(env->cwp - 1));
- } else if ((intno & 0x1c0) == TT_SPILL) {
- set_cwp(cwp_dec(env->cwp - env->cansave - 2));
- } else if ((intno & 0x1c0) == TT_FILL) {
- set_cwp(cwp_inc(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 = -1;
-}
-#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 (qemu_loglevel_mask(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";
- }
-
- qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
- count, name, intno,
- env->pc,
- env->npc, env->regwptr[6]);
- log_cpu_state(env, 0);
-#if 0
- {
- int i;
- uint8_t *ptr;
-
- qemu_log(" code=");
- ptr = (uint8_t *)env->pc;
- for(i = 0; i < 16; i++) {
- qemu_log(" %02x", ldub(ptr + i));
- }
- qemu_log("\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 = cwp_dec(env->cwp - 1);
- set_cwp(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 = -1;
-
-#if !defined(CONFIG_USER_ONLY)
- /* IRQ acknowledgment */
- if ((intno & ~15) == TT_EXTINT && env->qemu_irq_ack != NULL) {
- env->qemu_irq_ack(env->irq_manager, intno);
- }
-#endif
-}
-#endif
-
#if !defined(CONFIG_USER_ONLY)
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
NULL, it means that the function was called in C code (i.e. not
from generated code or from helper.c) */
/* XXX: fix it to restore all registers */
-void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
+void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx,
+ void *retaddr)
{
int ret;
CPUState *saved_env;
- /* XXX: hack to restore env in all cases, even if not called from
- generated code */
saved_env = env;
- env = cpu_single_env;
+ env = env1;
- ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
+ ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx);
if (ret) {
cpu_restore_state2(retaddr);
- cpu_loop_exit();
+ cpu_loop_exit(env);
}
env = saved_env;
}
#ifndef TARGET_SPARC64
#if !defined(CONFIG_USER_ONLY)
-void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
- int is_asi, int size)
+static void do_unassigned_access(target_phys_addr_t addr, int is_write,
+ int is_exec, int is_asi, int size)
{
- CPUState *saved_env;
int fault_type;
- /* XXX: hack to restore env in all cases, even if not called from
- generated code */
- saved_env = env;
- env = cpu_single_env;
#ifdef DEBUG_UNASSIGNED
if (is_asi)
printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
if (env->mmuregs[0] & MMU_NF) {
tlb_flush(env, 1);
}
-
- env = saved_env;
}
#endif
#else
static void do_unassigned_access(target_ulong addr, int is_write, int is_exec,
int is_asi, int size)
#else
-void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
- int is_asi, int size)
+static void do_unassigned_access(target_phys_addr_t addr, int is_write,
+ int is_exec, int is_asi, int size)
#endif
{
- CPUState *saved_env;
-
- /* XXX: hack to restore env in all cases, even if not called from
- generated code */
- saved_env = env;
- env = cpu_single_env;
-
#ifdef DEBUG_UNASSIGNED
printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
"\n", addr, env->pc);
raise_exception(TT_CODE_ACCESS);
else
raise_exception(TT_DATA_ACCESS);
-
- env = saved_env;
}
#endif
-
-#ifdef TARGET_SPARC64
-void helper_tick_set_count(void *opaque, uint64_t count)
-{
#if !defined(CONFIG_USER_ONLY)
- cpu_tick_set_count(opaque, count);
-#endif
-}
-
-uint64_t helper_tick_get_count(void *opaque)
+void cpu_unassigned_access(CPUState *env1, target_phys_addr_t addr,
+ int is_write, int is_exec, int is_asi, int size)
{
-#if !defined(CONFIG_USER_ONLY)
- return cpu_tick_get_count(opaque);
-#else
- return 0;
-#endif
-}
+ CPUState *saved_env;
-void helper_tick_set_limit(void *opaque, uint64_t limit)
-{
-#if !defined(CONFIG_USER_ONLY)
- cpu_tick_set_limit(opaque, limit);
-#endif
+ saved_env = env;
+ env = env1;
+ /* Ignore unassigned accesses outside of CPU context */
+ if (env1) {
+ do_unassigned_access(addr, is_write, is_exec, is_asi, size);
+ }
+ env = saved_env;
}
#endif