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