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" 21*a8d25326SMarkus Armbruster #include "qemu-common.h" 22cd71c089SLaurent Vivier #include "qemu.h" 23cd71c089SLaurent Vivier #include "cpu_loop-common.h" 24cd71c089SLaurent Vivier 25c37dcb4fSLaurent Vivier void cpu_loop(CPUSH4State *env) 26c37dcb4fSLaurent Vivier { 27dad1c8ecSRichard Henderson CPUState *cs = env_cpu(env); 28c37dcb4fSLaurent Vivier int trapnr, ret; 29c37dcb4fSLaurent Vivier target_siginfo_t info; 30c37dcb4fSLaurent Vivier 31c37dcb4fSLaurent Vivier while (1) { 32c37dcb4fSLaurent Vivier bool arch_interrupt = true; 33c37dcb4fSLaurent Vivier 34c37dcb4fSLaurent Vivier cpu_exec_start(cs); 35c37dcb4fSLaurent Vivier trapnr = cpu_exec(cs); 36c37dcb4fSLaurent Vivier cpu_exec_end(cs); 37c37dcb4fSLaurent Vivier process_queued_cpu_work(cs); 38c37dcb4fSLaurent Vivier 39c37dcb4fSLaurent Vivier switch (trapnr) { 40c37dcb4fSLaurent Vivier case 0x160: 41c37dcb4fSLaurent Vivier env->pc += 2; 42c37dcb4fSLaurent Vivier ret = do_syscall(env, 43c37dcb4fSLaurent Vivier env->gregs[3], 44c37dcb4fSLaurent Vivier env->gregs[4], 45c37dcb4fSLaurent Vivier env->gregs[5], 46c37dcb4fSLaurent Vivier env->gregs[6], 47c37dcb4fSLaurent Vivier env->gregs[7], 48c37dcb4fSLaurent Vivier env->gregs[0], 49c37dcb4fSLaurent Vivier env->gregs[1], 50c37dcb4fSLaurent Vivier 0, 0); 51c37dcb4fSLaurent Vivier if (ret == -TARGET_ERESTARTSYS) { 52c37dcb4fSLaurent Vivier env->pc -= 2; 53c37dcb4fSLaurent Vivier } else if (ret != -TARGET_QEMU_ESIGRETURN) { 54c37dcb4fSLaurent Vivier env->gregs[0] = ret; 55c37dcb4fSLaurent Vivier } 56c37dcb4fSLaurent Vivier break; 57c37dcb4fSLaurent Vivier case EXCP_INTERRUPT: 58c37dcb4fSLaurent Vivier /* just indicate that signals should be handled asap */ 59c37dcb4fSLaurent Vivier break; 60c37dcb4fSLaurent Vivier case EXCP_DEBUG: 61b10089a1SPeter Maydell info.si_signo = TARGET_SIGTRAP; 62c37dcb4fSLaurent Vivier info.si_errno = 0; 63c37dcb4fSLaurent Vivier info.si_code = TARGET_TRAP_BRKPT; 64c37dcb4fSLaurent Vivier queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); 65c37dcb4fSLaurent Vivier break; 66c37dcb4fSLaurent Vivier case 0xa0: 67c37dcb4fSLaurent Vivier case 0xc0: 68c37dcb4fSLaurent Vivier info.si_signo = TARGET_SIGSEGV; 69c37dcb4fSLaurent Vivier info.si_errno = 0; 70c37dcb4fSLaurent Vivier info.si_code = TARGET_SEGV_MAPERR; 71c37dcb4fSLaurent Vivier info._sifields._sigfault._addr = env->tea; 72c37dcb4fSLaurent Vivier queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); 73c37dcb4fSLaurent Vivier break; 74c37dcb4fSLaurent Vivier case EXCP_ATOMIC: 75c37dcb4fSLaurent Vivier cpu_exec_step_atomic(cs); 76c37dcb4fSLaurent Vivier arch_interrupt = false; 77c37dcb4fSLaurent Vivier break; 78c37dcb4fSLaurent Vivier default: 7984ca4fa9SPhilippe Mathieu-Daudé fprintf(stderr, "Unhandled trap: 0x%x\n", trapnr); 8090c84c56SMarkus Armbruster cpu_dump_state(cs, stderr, 0); 81c37dcb4fSLaurent Vivier exit(EXIT_FAILURE); 82c37dcb4fSLaurent Vivier } 83c37dcb4fSLaurent Vivier process_pending_signals (env); 84c37dcb4fSLaurent Vivier 85c37dcb4fSLaurent Vivier /* Most of the traps imply an exception or interrupt, which 86c37dcb4fSLaurent Vivier implies an REI instruction has been executed. Which means 87c37dcb4fSLaurent Vivier that LDST (aka LOK_ADDR) should be cleared. But there are 88c37dcb4fSLaurent Vivier a few exceptions for traps internal to QEMU. */ 89c37dcb4fSLaurent Vivier if (arch_interrupt) { 90c37dcb4fSLaurent Vivier env->lock_addr = -1; 91c37dcb4fSLaurent Vivier } 92c37dcb4fSLaurent Vivier } 93c37dcb4fSLaurent Vivier } 94c37dcb4fSLaurent Vivier 95cd71c089SLaurent Vivier void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) 96cd71c089SLaurent Vivier { 97c37dcb4fSLaurent Vivier int i; 98c37dcb4fSLaurent Vivier 99c37dcb4fSLaurent Vivier for(i = 0; i < 16; i++) { 100c37dcb4fSLaurent Vivier env->gregs[i] = regs->regs[i]; 101c37dcb4fSLaurent Vivier } 102c37dcb4fSLaurent Vivier env->pc = regs->pc; 103cd71c089SLaurent Vivier } 104