1cd71c089SLaurent Vivier /* 2cd71c089SLaurent Vivier * qemu user cpu loop 3cd71c089SLaurent Vivier * 4cd71c089SLaurent Vivier * Copyright (c) 2003-2008 Fabrice Bellard 5cd71c089SLaurent Vivier * 6cd71c089SLaurent Vivier * This program is free software; you can redistribute it and/or modify 7cd71c089SLaurent Vivier * it under the terms of the GNU General Public License as published by 8cd71c089SLaurent Vivier * the Free Software Foundation; either version 2 of the License, or 9cd71c089SLaurent Vivier * (at your option) any later version. 10cd71c089SLaurent Vivier * 11cd71c089SLaurent Vivier * This program is distributed in the hope that it will be useful, 12cd71c089SLaurent Vivier * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cd71c089SLaurent Vivier * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14cd71c089SLaurent Vivier * GNU General Public License for more details. 15cd71c089SLaurent Vivier * 16cd71c089SLaurent Vivier * You should have received a copy of the GNU General Public License 17cd71c089SLaurent Vivier * along with this program; if not, see <http://www.gnu.org/licenses/>. 18cd71c089SLaurent Vivier */ 19cd71c089SLaurent Vivier 20cd71c089SLaurent Vivier #include "qemu/osdep.h" 21a8d25326SMarkus Armbruster #include "qemu-common.h" 22cd71c089SLaurent Vivier #include "qemu.h" 23*cdf06ce5SPhilippe Mathieu-Daudé #include "qemu/timer.h" 243b249d26SPeter Maydell #include "user-internals.h" 25cd71c089SLaurent Vivier #include "cpu_loop-common.h" 262113aed6SPeter Maydell #include "signal-common.h" 27cd71c089SLaurent Vivier 2811400516SLaurent Vivier static inline uint64_t cpu_ppc_get_tb(CPUPPCState *env) 2911400516SLaurent Vivier { 3011400516SLaurent Vivier return cpu_get_host_ticks(); 3111400516SLaurent Vivier } 3211400516SLaurent Vivier 3311400516SLaurent Vivier uint64_t cpu_ppc_load_tbl(CPUPPCState *env) 3411400516SLaurent Vivier { 3511400516SLaurent Vivier return cpu_ppc_get_tb(env); 3611400516SLaurent Vivier } 3711400516SLaurent Vivier 3811400516SLaurent Vivier uint32_t cpu_ppc_load_tbu(CPUPPCState *env) 3911400516SLaurent Vivier { 4011400516SLaurent Vivier return cpu_ppc_get_tb(env) >> 32; 4111400516SLaurent Vivier } 4211400516SLaurent Vivier 4311400516SLaurent Vivier uint64_t cpu_ppc_load_atbl(CPUPPCState *env) 4411400516SLaurent Vivier { 4511400516SLaurent Vivier return cpu_ppc_get_tb(env); 4611400516SLaurent Vivier } 4711400516SLaurent Vivier 4811400516SLaurent Vivier uint32_t cpu_ppc_load_atbu(CPUPPCState *env) 4911400516SLaurent Vivier { 5011400516SLaurent Vivier return cpu_ppc_get_tb(env) >> 32; 5111400516SLaurent Vivier } 5211400516SLaurent Vivier 535d62725bSSuraj Jitindar Singh uint64_t cpu_ppc_load_vtb(CPUPPCState *env) 545d62725bSSuraj Jitindar Singh { 555d62725bSSuraj Jitindar Singh return cpu_ppc_get_tb(env); 565d62725bSSuraj Jitindar Singh } 575d62725bSSuraj Jitindar Singh 5811400516SLaurent Vivier /* XXX: to be fixed */ 5911400516SLaurent Vivier int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp) 6011400516SLaurent Vivier { 6111400516SLaurent Vivier return -1; 6211400516SLaurent Vivier } 6311400516SLaurent Vivier 6411400516SLaurent Vivier int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val) 6511400516SLaurent Vivier { 6611400516SLaurent Vivier return -1; 6711400516SLaurent Vivier } 6811400516SLaurent Vivier 6911400516SLaurent Vivier void cpu_loop(CPUPPCState *env) 7011400516SLaurent Vivier { 71db70b311SRichard Henderson CPUState *cs = env_cpu(env); 72d30e60e7SRichard Henderson int trapnr, si_signo, si_code; 7311400516SLaurent Vivier target_ulong ret; 7411400516SLaurent Vivier 7511400516SLaurent Vivier for(;;) { 7614db1899SRichard Henderson bool arch_interrupt; 7714db1899SRichard Henderson 7811400516SLaurent Vivier cpu_exec_start(cs); 7911400516SLaurent Vivier trapnr = cpu_exec(cs); 8011400516SLaurent Vivier cpu_exec_end(cs); 8111400516SLaurent Vivier process_queued_cpu_work(cs); 8211400516SLaurent Vivier 8314db1899SRichard Henderson arch_interrupt = true; 8411400516SLaurent Vivier switch (trapnr) { 8511400516SLaurent Vivier case POWERPC_EXCP_NONE: 8611400516SLaurent Vivier /* Just go on */ 8711400516SLaurent Vivier break; 8811400516SLaurent Vivier case POWERPC_EXCP_CRITICAL: /* Critical input */ 8911400516SLaurent Vivier cpu_abort(cs, "Critical interrupt while in user mode. " 9011400516SLaurent Vivier "Aborting\n"); 9111400516SLaurent Vivier break; 9211400516SLaurent Vivier case POWERPC_EXCP_MCHECK: /* Machine check exception */ 9311400516SLaurent Vivier cpu_abort(cs, "Machine check exception while in user mode. " 9411400516SLaurent Vivier "Aborting\n"); 9511400516SLaurent Vivier break; 9611400516SLaurent Vivier case POWERPC_EXCP_DSI: /* Data storage exception */ 9711400516SLaurent Vivier case POWERPC_EXCP_ISI: /* Instruction storage exception */ 98d30e60e7SRichard Henderson /* FIXME: handle maperr in ppc_cpu_record_sigsegv. */ 99d30e60e7SRichard Henderson force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR, 100d30e60e7SRichard Henderson env->spr[SPR_DAR]); 10111400516SLaurent Vivier break; 10211400516SLaurent Vivier case POWERPC_EXCP_EXTERNAL: /* External input */ 10311400516SLaurent Vivier cpu_abort(cs, "External interrupt while in user mode. " 10411400516SLaurent Vivier "Aborting\n"); 10511400516SLaurent Vivier break; 10611400516SLaurent Vivier case POWERPC_EXCP_PROGRAM: /* Program exception */ 10711400516SLaurent Vivier case POWERPC_EXCP_HV_EMU: /* HV emulation */ 10811400516SLaurent Vivier /* XXX: check this */ 10911400516SLaurent Vivier switch (env->error_code & ~0xF) { 11011400516SLaurent Vivier case POWERPC_EXCP_FP: 111d30e60e7SRichard Henderson si_signo = TARGET_SIGFPE; 11211400516SLaurent Vivier switch (env->error_code & 0xF) { 11311400516SLaurent Vivier case POWERPC_EXCP_FP_OX: 114d30e60e7SRichard Henderson si_code = TARGET_FPE_FLTOVF; 11511400516SLaurent Vivier break; 11611400516SLaurent Vivier case POWERPC_EXCP_FP_UX: 117d30e60e7SRichard Henderson si_code = TARGET_FPE_FLTUND; 11811400516SLaurent Vivier break; 11911400516SLaurent Vivier case POWERPC_EXCP_FP_ZX: 12011400516SLaurent Vivier case POWERPC_EXCP_FP_VXZDZ: 121d30e60e7SRichard Henderson si_code = TARGET_FPE_FLTDIV; 12211400516SLaurent Vivier break; 12311400516SLaurent Vivier case POWERPC_EXCP_FP_XX: 124d30e60e7SRichard Henderson si_code = TARGET_FPE_FLTRES; 12511400516SLaurent Vivier break; 12611400516SLaurent Vivier case POWERPC_EXCP_FP_VXSOFT: 127d30e60e7SRichard Henderson si_code = TARGET_FPE_FLTINV; 12811400516SLaurent Vivier break; 12911400516SLaurent Vivier case POWERPC_EXCP_FP_VXSNAN: 13011400516SLaurent Vivier case POWERPC_EXCP_FP_VXISI: 13111400516SLaurent Vivier case POWERPC_EXCP_FP_VXIDI: 13211400516SLaurent Vivier case POWERPC_EXCP_FP_VXIMZ: 13311400516SLaurent Vivier case POWERPC_EXCP_FP_VXVC: 13411400516SLaurent Vivier case POWERPC_EXCP_FP_VXSQRT: 13511400516SLaurent Vivier case POWERPC_EXCP_FP_VXCVI: 136d30e60e7SRichard Henderson si_code = TARGET_FPE_FLTSUB; 13711400516SLaurent Vivier break; 13811400516SLaurent Vivier default: 13911400516SLaurent Vivier EXCP_DUMP(env, "Unknown floating point exception (%02x)\n", 14011400516SLaurent Vivier env->error_code); 141d30e60e7SRichard Henderson si_code = 0; 14211400516SLaurent Vivier break; 14311400516SLaurent Vivier } 14411400516SLaurent Vivier break; 14511400516SLaurent Vivier case POWERPC_EXCP_INVAL: 146d30e60e7SRichard Henderson si_signo = TARGET_SIGILL; 14711400516SLaurent Vivier switch (env->error_code & 0xF) { 14811400516SLaurent Vivier case POWERPC_EXCP_INVAL_INVAL: 149d30e60e7SRichard Henderson si_code = TARGET_ILL_ILLOPC; 15011400516SLaurent Vivier break; 15111400516SLaurent Vivier case POWERPC_EXCP_INVAL_LSWX: 152d30e60e7SRichard Henderson si_code = TARGET_ILL_ILLOPN; 15311400516SLaurent Vivier break; 15411400516SLaurent Vivier case POWERPC_EXCP_INVAL_SPR: 155d30e60e7SRichard Henderson si_code = TARGET_ILL_PRVREG; 15611400516SLaurent Vivier break; 15711400516SLaurent Vivier case POWERPC_EXCP_INVAL_FP: 158d30e60e7SRichard Henderson si_code = TARGET_ILL_COPROC; 15911400516SLaurent Vivier break; 16011400516SLaurent Vivier default: 16111400516SLaurent Vivier EXCP_DUMP(env, "Unknown invalid operation (%02x)\n", 16211400516SLaurent Vivier env->error_code & 0xF); 163d30e60e7SRichard Henderson si_code = TARGET_ILL_ILLADR; 16411400516SLaurent Vivier break; 16511400516SLaurent Vivier } 16611400516SLaurent Vivier break; 16711400516SLaurent Vivier case POWERPC_EXCP_PRIV: 168d30e60e7SRichard Henderson si_signo = TARGET_SIGILL; 16911400516SLaurent Vivier switch (env->error_code & 0xF) { 17011400516SLaurent Vivier case POWERPC_EXCP_PRIV_OPC: 171d30e60e7SRichard Henderson si_code = TARGET_ILL_PRVOPC; 17211400516SLaurent Vivier break; 17311400516SLaurent Vivier case POWERPC_EXCP_PRIV_REG: 174d30e60e7SRichard Henderson si_code = TARGET_ILL_PRVREG; 17511400516SLaurent Vivier break; 17611400516SLaurent Vivier default: 17711400516SLaurent Vivier EXCP_DUMP(env, "Unknown privilege violation (%02x)\n", 17811400516SLaurent Vivier env->error_code & 0xF); 179d30e60e7SRichard Henderson si_code = TARGET_ILL_PRVOPC; 18011400516SLaurent Vivier break; 18111400516SLaurent Vivier } 18211400516SLaurent Vivier break; 18311400516SLaurent Vivier case POWERPC_EXCP_TRAP: 18411400516SLaurent Vivier cpu_abort(cs, "Tried to call a TRAP\n"); 18511400516SLaurent Vivier break; 18611400516SLaurent Vivier default: 18711400516SLaurent Vivier /* Should not happen ! */ 18811400516SLaurent Vivier cpu_abort(cs, "Unknown program exception (%02x)\n", 18911400516SLaurent Vivier env->error_code); 19011400516SLaurent Vivier break; 19111400516SLaurent Vivier } 192d30e60e7SRichard Henderson force_sig_fault(si_signo, si_code, env->nip); 19311400516SLaurent Vivier break; 19411400516SLaurent Vivier case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ 195d30e60e7SRichard Henderson case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */ 196d30e60e7SRichard Henderson case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */ 197d30e60e7SRichard Henderson case POWERPC_EXCP_VPU: /* Vector unavailable exception */ 198d30e60e7SRichard Henderson force_sig_fault(TARGET_SIGILL, TARGET_ILL_COPROC, env->nip); 19911400516SLaurent Vivier break; 20011400516SLaurent Vivier case POWERPC_EXCP_SYSCALL: /* System call exception */ 2013c89b8d6SNicholas Piggin case POWERPC_EXCP_SYSCALL_VECTORED: 20211400516SLaurent Vivier cpu_abort(cs, "Syscall exception while in user mode. " 20311400516SLaurent Vivier "Aborting\n"); 20411400516SLaurent Vivier break; 20511400516SLaurent Vivier case POWERPC_EXCP_DECR: /* Decrementer exception */ 20611400516SLaurent Vivier cpu_abort(cs, "Decrementer interrupt while in user mode. " 20711400516SLaurent Vivier "Aborting\n"); 20811400516SLaurent Vivier break; 20911400516SLaurent Vivier case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ 21011400516SLaurent Vivier cpu_abort(cs, "Fix interval timer interrupt while in user mode. " 21111400516SLaurent Vivier "Aborting\n"); 21211400516SLaurent Vivier break; 21311400516SLaurent Vivier case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ 21411400516SLaurent Vivier cpu_abort(cs, "Watchdog timer interrupt while in user mode. " 21511400516SLaurent Vivier "Aborting\n"); 21611400516SLaurent Vivier break; 21711400516SLaurent Vivier case POWERPC_EXCP_DTLB: /* Data TLB error */ 21811400516SLaurent Vivier cpu_abort(cs, "Data TLB exception while in user mode. " 21911400516SLaurent Vivier "Aborting\n"); 22011400516SLaurent Vivier break; 22111400516SLaurent Vivier case POWERPC_EXCP_ITLB: /* Instruction TLB error */ 22211400516SLaurent Vivier cpu_abort(cs, "Instruction TLB exception while in user mode. " 22311400516SLaurent Vivier "Aborting\n"); 22411400516SLaurent Vivier break; 22511400516SLaurent Vivier case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */ 22611400516SLaurent Vivier cpu_abort(cs, "Embedded floating-point data IRQ not handled\n"); 22711400516SLaurent Vivier break; 22811400516SLaurent Vivier case POWERPC_EXCP_EFPRI: /* Embedded floating-point round IRQ */ 22911400516SLaurent Vivier cpu_abort(cs, "Embedded floating-point round IRQ not handled\n"); 23011400516SLaurent Vivier break; 23111400516SLaurent Vivier case POWERPC_EXCP_EPERFM: /* Embedded performance monitor IRQ */ 23211400516SLaurent Vivier cpu_abort(cs, "Performance monitor exception not handled\n"); 23311400516SLaurent Vivier break; 23411400516SLaurent Vivier case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */ 23511400516SLaurent Vivier cpu_abort(cs, "Doorbell interrupt while in user mode. " 23611400516SLaurent Vivier "Aborting\n"); 23711400516SLaurent Vivier break; 23811400516SLaurent Vivier case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */ 23911400516SLaurent Vivier cpu_abort(cs, "Doorbell critical interrupt while in user mode. " 24011400516SLaurent Vivier "Aborting\n"); 24111400516SLaurent Vivier break; 24211400516SLaurent Vivier case POWERPC_EXCP_RESET: /* System reset exception */ 24311400516SLaurent Vivier cpu_abort(cs, "Reset interrupt while in user mode. " 24411400516SLaurent Vivier "Aborting\n"); 24511400516SLaurent Vivier break; 24611400516SLaurent Vivier case POWERPC_EXCP_DSEG: /* Data segment exception */ 24711400516SLaurent Vivier cpu_abort(cs, "Data segment exception while in user mode. " 24811400516SLaurent Vivier "Aborting\n"); 24911400516SLaurent Vivier break; 25011400516SLaurent Vivier case POWERPC_EXCP_ISEG: /* Instruction segment exception */ 25111400516SLaurent Vivier cpu_abort(cs, "Instruction segment exception " 25211400516SLaurent Vivier "while in user mode. Aborting\n"); 25311400516SLaurent Vivier break; 25411400516SLaurent Vivier /* PowerPC 64 with hypervisor mode support */ 25511400516SLaurent Vivier case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ 25611400516SLaurent Vivier cpu_abort(cs, "Hypervisor decrementer interrupt " 25711400516SLaurent Vivier "while in user mode. Aborting\n"); 25811400516SLaurent Vivier break; 25911400516SLaurent Vivier case POWERPC_EXCP_TRACE: /* Trace exception */ 26011400516SLaurent Vivier /* Nothing to do: 26111400516SLaurent Vivier * we use this exception to emulate step-by-step execution mode. 26211400516SLaurent Vivier */ 26311400516SLaurent Vivier break; 26411400516SLaurent Vivier /* PowerPC 64 with hypervisor mode support */ 26511400516SLaurent Vivier case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ 26611400516SLaurent Vivier cpu_abort(cs, "Hypervisor data storage exception " 26711400516SLaurent Vivier "while in user mode. Aborting\n"); 26811400516SLaurent Vivier break; 26911400516SLaurent Vivier case POWERPC_EXCP_HISI: /* Hypervisor instruction storage excp */ 27011400516SLaurent Vivier cpu_abort(cs, "Hypervisor instruction storage exception " 27111400516SLaurent Vivier "while in user mode. Aborting\n"); 27211400516SLaurent Vivier break; 27311400516SLaurent Vivier case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */ 27411400516SLaurent Vivier cpu_abort(cs, "Hypervisor data segment exception " 27511400516SLaurent Vivier "while in user mode. Aborting\n"); 27611400516SLaurent Vivier break; 27711400516SLaurent Vivier case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment excp */ 27811400516SLaurent Vivier cpu_abort(cs, "Hypervisor instruction segment exception " 27911400516SLaurent Vivier "while in user mode. Aborting\n"); 28011400516SLaurent Vivier break; 28111400516SLaurent Vivier case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */ 28211400516SLaurent Vivier cpu_abort(cs, "Programmable interval timer interrupt " 28311400516SLaurent Vivier "while in user mode. Aborting\n"); 28411400516SLaurent Vivier break; 28511400516SLaurent Vivier case POWERPC_EXCP_EMUL: /* Emulation trap exception */ 28611400516SLaurent Vivier cpu_abort(cs, "Emulation trap exception not handled\n"); 28711400516SLaurent Vivier break; 28811400516SLaurent Vivier case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */ 28911400516SLaurent Vivier cpu_abort(cs, "Instruction fetch TLB exception " 29011400516SLaurent Vivier "while in user-mode. Aborting"); 29111400516SLaurent Vivier break; 29211400516SLaurent Vivier case POWERPC_EXCP_DLTLB: /* Data load TLB miss */ 29311400516SLaurent Vivier cpu_abort(cs, "Data load TLB exception while in user-mode. " 29411400516SLaurent Vivier "Aborting"); 29511400516SLaurent Vivier break; 29611400516SLaurent Vivier case POWERPC_EXCP_DSTLB: /* Data store TLB miss */ 29711400516SLaurent Vivier cpu_abort(cs, "Data store TLB exception while in user-mode. " 29811400516SLaurent Vivier "Aborting"); 29911400516SLaurent Vivier break; 30011400516SLaurent Vivier case POWERPC_EXCP_FPA: /* Floating-point assist exception */ 30111400516SLaurent Vivier cpu_abort(cs, "Floating-point assist exception not handled\n"); 30211400516SLaurent Vivier break; 30311400516SLaurent Vivier case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ 30411400516SLaurent Vivier cpu_abort(cs, "Instruction address breakpoint exception " 30511400516SLaurent Vivier "not handled\n"); 30611400516SLaurent Vivier break; 30711400516SLaurent Vivier case POWERPC_EXCP_SMI: /* System management interrupt */ 30811400516SLaurent Vivier cpu_abort(cs, "System management interrupt while in user mode. " 30911400516SLaurent Vivier "Aborting\n"); 31011400516SLaurent Vivier break; 31111400516SLaurent Vivier case POWERPC_EXCP_THERM: /* Thermal interrupt */ 31211400516SLaurent Vivier cpu_abort(cs, "Thermal interrupt interrupt while in user mode. " 31311400516SLaurent Vivier "Aborting\n"); 31411400516SLaurent Vivier break; 31511400516SLaurent Vivier case POWERPC_EXCP_PERFM: /* Embedded performance monitor IRQ */ 31611400516SLaurent Vivier cpu_abort(cs, "Performance monitor exception not handled\n"); 31711400516SLaurent Vivier break; 31811400516SLaurent Vivier case POWERPC_EXCP_VPUA: /* Vector assist exception */ 31911400516SLaurent Vivier cpu_abort(cs, "Vector assist exception not handled\n"); 32011400516SLaurent Vivier break; 32111400516SLaurent Vivier case POWERPC_EXCP_SOFTP: /* Soft patch exception */ 32211400516SLaurent Vivier cpu_abort(cs, "Soft patch exception not handled\n"); 32311400516SLaurent Vivier break; 32411400516SLaurent Vivier case POWERPC_EXCP_MAINT: /* Maintenance exception */ 32511400516SLaurent Vivier cpu_abort(cs, "Maintenance exception while in user mode. " 32611400516SLaurent Vivier "Aborting\n"); 32711400516SLaurent Vivier break; 32811400516SLaurent Vivier case POWERPC_EXCP_SYSCALL_USER: 32911400516SLaurent Vivier /* system call in user-mode emulation */ 33011400516SLaurent Vivier /* WARNING: 33111400516SLaurent Vivier * PPC ABI uses overflow flag in cr0 to signal an error 33211400516SLaurent Vivier * in syscalls. 33311400516SLaurent Vivier */ 33411400516SLaurent Vivier env->crf[0] &= ~0x1; 33511400516SLaurent Vivier env->nip += 4; 33611400516SLaurent Vivier ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4], 33711400516SLaurent Vivier env->gpr[5], env->gpr[6], env->gpr[7], 33811400516SLaurent Vivier env->gpr[8], 0, 0); 339af254a27SRichard Henderson if (ret == -QEMU_ERESTARTSYS) { 34011400516SLaurent Vivier env->nip -= 4; 34111400516SLaurent Vivier break; 34211400516SLaurent Vivier } 34357a0c938SRichard Henderson if (ret == (target_ulong)(-QEMU_ESIGRETURN)) { 34411400516SLaurent Vivier /* Returning from a successful sigreturn syscall. 34511400516SLaurent Vivier Avoid corrupting register state. */ 34611400516SLaurent Vivier break; 34711400516SLaurent Vivier } 34811400516SLaurent Vivier if (ret > (target_ulong)(-515)) { 34911400516SLaurent Vivier env->crf[0] |= 0x1; 35011400516SLaurent Vivier ret = -ret; 35111400516SLaurent Vivier } 35211400516SLaurent Vivier env->gpr[3] = ret; 35311400516SLaurent Vivier break; 35411400516SLaurent Vivier case EXCP_DEBUG: 355d30e60e7SRichard Henderson force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->nip); 35611400516SLaurent Vivier break; 35711400516SLaurent Vivier case EXCP_INTERRUPT: 35811400516SLaurent Vivier /* just indicate that signals should be handled asap */ 35911400516SLaurent Vivier break; 36011400516SLaurent Vivier case EXCP_ATOMIC: 36111400516SLaurent Vivier cpu_exec_step_atomic(cs); 36214db1899SRichard Henderson arch_interrupt = false; 36311400516SLaurent Vivier break; 36411400516SLaurent Vivier default: 36511400516SLaurent Vivier cpu_abort(cs, "Unknown exception 0x%x. Aborting\n", trapnr); 36611400516SLaurent Vivier break; 36711400516SLaurent Vivier } 36811400516SLaurent Vivier process_pending_signals(env); 36914db1899SRichard Henderson 37014db1899SRichard Henderson /* Most of the traps imply a transition through kernel mode, 37114db1899SRichard Henderson * which implies an REI instruction has been executed. Which 37214db1899SRichard Henderson * means that RX and LOCK_ADDR should be cleared. But there 37314db1899SRichard Henderson * are a few exceptions for traps internal to QEMU. 37414db1899SRichard Henderson */ 37514db1899SRichard Henderson if (arch_interrupt) { 37614db1899SRichard Henderson env->reserve_addr = -1; 37714db1899SRichard Henderson } 37811400516SLaurent Vivier } 37911400516SLaurent Vivier } 38011400516SLaurent Vivier 381cd71c089SLaurent Vivier void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) 382cd71c089SLaurent Vivier { 38311400516SLaurent Vivier int i; 38411400516SLaurent Vivier 38511400516SLaurent Vivier #if defined(TARGET_PPC64) 38611400516SLaurent Vivier int flag = (env->insns_flags2 & PPC2_BOOKE206) ? MSR_CM : MSR_SF; 38711400516SLaurent Vivier #if defined(TARGET_ABI32) 38875da4997SRichard Henderson ppc_store_msr(env, env->msr & ~((target_ulong)1 << flag)); 38911400516SLaurent Vivier #else 39075da4997SRichard Henderson ppc_store_msr(env, env->msr | (target_ulong)1 << flag); 39111400516SLaurent Vivier #endif 39211400516SLaurent Vivier #endif 39375da4997SRichard Henderson 39411400516SLaurent Vivier env->nip = regs->nip; 39511400516SLaurent Vivier for(i = 0; i < 32; i++) { 39611400516SLaurent Vivier env->gpr[i] = regs->gpr[i]; 39711400516SLaurent Vivier } 398cd71c089SLaurent Vivier } 399