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