static void do_rte(CPUM68KState *env) { uint32_t sp; uint32_t fmt; sp = env->aregs[7]; fmt = cpu_ldl_kernel(env, sp); env->pc = cpu_ldl_kernel(env, sp + 4); sp |= (fmt >> 28) & 3; env->sr = fmt & 0xffff; m68k_switch_sp(env); env->aregs[7] = sp + 8; }
static void do_rte(void) { uint32_t sp; uint32_t fmt; sp = env->aregs[7]; fmt = ldl_kernel(sp); env->pc = ldl_kernel(sp + 4); sp |= (fmt >> 28) & 3; env->sr = fmt & 0xffff; m68k_switch_sp(env); env->aregs[7] = sp + 8; }
void cpu_reset(CPUM68KState *env) { if (qemu_loglevel_mask(CPU_LOG_RESET)) { qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); log_cpu_state(env, 0); } memset(env, 0, offsetof(CPUM68KState, breakpoints)); #if !defined (CONFIG_USER_ONLY) env->sr = 0x2700; #endif m68k_switch_sp(env); /* ??? FP regs should be initialized to NaN. */ env->cc_op = CC_OP_FLAGS; /* TODO: We should set PC from the interrupt vector. */ env->pc = 0; tlb_flush(env, 1); }
/* CPUClass::reset() */ static void m68k_cpu_reset(CPUState *s) { M68kCPU *cpu = M68K_CPU(s); M68kCPUClass *mcc = M68K_CPU_GET_CLASS(cpu); CPUM68KState *env = &cpu->env; mcc->parent_reset(s); memset(env, 0, offsetof(CPUM68KState, features)); #if !defined(CONFIG_USER_ONLY) env->sr = 0x2700; #endif m68k_switch_sp(env); /* ??? FP regs should be initialized to NaN. */ env->cc_op = CC_OP_FLAGS; /* TODO: We should set PC from the interrupt vector. */ env->pc = 0; tlb_flush(s, 1); }
void HELPER(movec)(CPUM68KState *env, uint32_t reg, uint32_t val) { switch (reg) { case 0x02: /* CACR */ env->cacr = val; m68k_switch_sp(env); break; case 0x04: case 0x05: case 0x06: case 0x07: /* ACR[0-3] */ /* TODO: Implement Access Control Registers. */ break; case 0x801: /* VBR */ env->vbr = val; break; /* TODO: Implement control registers. */ default: cpu_abort(env, "Unimplemented control register write 0x%x = 0x%x\n", reg, val); } }
/* CPUClass::reset() */ static void m68k_cpu_reset(CPUState *s) { M68kCPU *cpu = M68K_CPU(s); M68kCPUClass *mcc = M68K_CPU_GET_CLASS(cpu); CPUM68KState *env = &cpu->env; if (qemu_loglevel_mask(CPU_LOG_RESET)) { qemu_log("CPU Reset (CPU %d)\n", s->cpu_index); log_cpu_state(env, 0); } mcc->parent_reset(s); memset(env, 0, offsetof(CPUM68KState, breakpoints)); #if !defined(CONFIG_USER_ONLY) env->sr = 0x2700; #endif m68k_switch_sp(env); /* ??? FP regs should be initialized to NaN. */ env->cc_op = CC_OP_FLAGS; /* TODO: We should set PC from the interrupt vector. */ env->pc = 0; tlb_flush(env, 1); }
static void do_interrupt_all(CPUM68KState *env, int is_hw) { CPUState *cs; uint32_t sp; uint32_t fmt; uint32_t retaddr; uint32_t vector; fmt = 0; retaddr = env->pc; if (!is_hw) { switch (env->exception_index) { case EXCP_RTE: /* Return from an exception. */ do_rte(env); return; case EXCP_HALT_INSN: if (semihosting_enabled && (env->sr & SR_S) != 0 && (env->pc & 3) == 0 && cpu_lduw_code(env, env->pc - 4) == 0x4e71 && cpu_ldl_code(env, env->pc) == 0x4e7bf000) { env->pc += 4; do_m68k_semihosting(env, env->dregs[0]); return; } cs = CPU(m68k_env_get_cpu(env)); cs->halted = 1; env->exception_index = EXCP_HLT; cpu_loop_exit(env); return; } if (env->exception_index >= EXCP_TRAP0 && env->exception_index <= EXCP_TRAP15) { /* Move the PC after the trap instruction. */ retaddr += 2; } } vector = env->exception_index << 2; sp = env->aregs[7]; fmt |= 0x40000000; fmt |= (sp & 3) << 28; fmt |= vector << 16; fmt |= env->sr; env->sr |= SR_S; if (is_hw) { env->sr = (env->sr & ~SR_I) | (env->pending_level << SR_I_SHIFT); env->sr &= ~SR_M; } m68k_switch_sp(env); /* ??? This could cause MMU faults. */ sp &= ~3; sp -= 4; cpu_stl_kernel(env, sp, retaddr); sp -= 4; cpu_stl_kernel(env, sp, fmt); env->aregs[7] = sp; /* Jump to vector. */ env->pc = cpu_ldl_kernel(env, env->vbr + vector); }