}
#endif
-#ifdef TARGET_SPARC
-#define SPARC64_STACK_BIAS 2047
-
-/* #define DEBUG_WIN */
-/*
- * WARNING: dealing with register windows _is_ complicated. More info
- * can be found at http://www.sics.se/~psm/sparcstack.html
- */
-static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
-{
- index = (index + cwp * 16) % (16 * env->nwindows);
- /*
- * wrap handling : if cwp is on the last window, then we use the
- * registers 'after' the end
- */
- if (index < 8 && env->cwp == env->nwindows - 1) {
- index += 16 * env->nwindows;
- }
- return index;
-}
-
-/* save the register window 'cwp1' */
-static inline void save_window_offset(CPUSPARCState *env, int cwp1)
-{
- unsigned int i;
- abi_ulong sp_ptr;
-
- sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
-#ifdef TARGET_SPARC64
- if (sp_ptr & 3) {
- sp_ptr += SPARC64_STACK_BIAS;
- }
-#endif
-#if defined(DEBUG_WIN)
- printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
- sp_ptr, cwp1);
-#endif
- for (i = 0; i < 16; i++) {
- /* FIXME - what to do if put_user() fails? */
- put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
- sp_ptr += sizeof(abi_ulong);
- }
-}
-
-static void save_window(CPUSPARCState *env)
-{
-#ifndef TARGET_SPARC64
- unsigned int new_wim;
- new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
- ((1LL << env->nwindows) - 1);
- save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
- env->wim = new_wim;
-#else
- /*
- * cansave is zero if the spill trap handler is triggered by `save` and
- * nonzero if triggered by a `flushw`
- */
- save_window_offset(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
- env->cansave++;
- env->canrestore--;
-#endif
-}
-
-static void restore_window(CPUSPARCState *env)
-{
-#ifndef TARGET_SPARC64
- unsigned int new_wim;
-#endif
- unsigned int i, cwp1;
- abi_ulong sp_ptr;
-
-#ifndef TARGET_SPARC64
- new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
- ((1LL << env->nwindows) - 1);
-#endif
-
- /* restore the invalid window */
- cwp1 = cpu_cwp_inc(env, env->cwp + 1);
- sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
-#ifdef TARGET_SPARC64
- if (sp_ptr & 3) {
- sp_ptr += SPARC64_STACK_BIAS;
- }
-#endif
-#if defined(DEBUG_WIN)
- printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
- sp_ptr, cwp1);
-#endif
- for (i = 0; i < 16; i++) {
- /* FIXME - what to do if get_user() fails? */
- get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
- sp_ptr += sizeof(abi_ulong);
- }
-#ifdef TARGET_SPARC64
- env->canrestore++;
- if (env->cleanwin < env->nwindows - 1) {
- env->cleanwin++;
- }
- env->cansave--;
-#else
- env->wim = new_wim;
-#endif
-}
-
-static void flush_windows(CPUSPARCState *env)
-{
- int offset, cwp1;
-
- offset = 1;
- for (;;) {
- /* if restore would invoke restore_window(), then we can stop */
- cwp1 = cpu_cwp_inc(env, env->cwp + offset);
-#ifndef TARGET_SPARC64
- if (env->wim & (1 << cwp1)) {
- break;
- }
-#else
- if (env->canrestore == 0) {
- break;
- }
- env->cansave++;
- env->canrestore--;
-#endif
- save_window_offset(env, cwp1);
- offset++;
- }
- cwp1 = cpu_cwp_inc(env, env->cwp + 1);
-#ifndef TARGET_SPARC64
- /* set wim so that restore will reload the registers */
- env->wim = 1 << cwp1;
-#endif
-#if defined(DEBUG_WIN)
- printf("flush_windows: nb=%d\n", offset - 1);
-#endif
-}
-
-void cpu_loop(CPUSPARCState *env)
-{
- CPUState *cs = env_cpu(env);
- int trapnr, ret, syscall_nr;
- /* target_siginfo_t info; */
-
- while (1) {
- cpu_exec_start(cs);
- trapnr = cpu_exec(cs);
- cpu_exec_end(cs);
- process_queued_cpu_work(cs);
-
- switch (trapnr) {
-#ifndef TARGET_SPARC64
- case 0x80:
-#else
- /* FreeBSD uses 0x141 for syscalls too */
- case 0x141:
- if (bsd_type != target_freebsd) {
- goto badtrap;
- }
- /* fallthrough */
- case 0x100:
-#endif
- syscall_nr = env->gregs[1];
- if (bsd_type == target_freebsd)
- ret = do_freebsd_syscall(env, syscall_nr,
- env->regwptr[0], env->regwptr[1],
- env->regwptr[2], env->regwptr[3],
- env->regwptr[4], env->regwptr[5],
- 0, 0);
- else if (bsd_type == target_netbsd)
- ret = do_netbsd_syscall(env, syscall_nr,
- env->regwptr[0], env->regwptr[1],
- env->regwptr[2], env->regwptr[3],
- env->regwptr[4], env->regwptr[5]);
- else { /* if (bsd_type == target_openbsd) */
-#if defined(TARGET_SPARC64)
- syscall_nr &= ~(TARGET_OPENBSD_SYSCALL_G7RFLAG |
- TARGET_OPENBSD_SYSCALL_G2RFLAG);
-#endif
- ret = do_openbsd_syscall(env, syscall_nr,
- env->regwptr[0], env->regwptr[1],
- env->regwptr[2], env->regwptr[3],
- env->regwptr[4], env->regwptr[5]);
- }
- if ((unsigned int)ret >= (unsigned int)(-515)) {
- ret = -ret;
-#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
- env->xcc |= PSR_CARRY;
-#else
- env->psr |= PSR_CARRY;
-#endif
- } else {
-#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
- env->xcc &= ~PSR_CARRY;
-#else
- env->psr &= ~PSR_CARRY;
-#endif
- }
- env->regwptr[0] = ret;
- /* next instruction */
-#if defined(TARGET_SPARC64)
- if (bsd_type == target_openbsd &&
- env->gregs[1] & TARGET_OPENBSD_SYSCALL_G2RFLAG) {
- env->pc = env->gregs[2];
- env->npc = env->pc + 4;
- } else if (bsd_type == target_openbsd &&
- env->gregs[1] & TARGET_OPENBSD_SYSCALL_G7RFLAG) {
- env->pc = env->gregs[7];
- env->npc = env->pc + 4;
- } else {
- env->pc = env->npc;
- env->npc = env->npc + 4;
- }
-#else
- env->pc = env->npc;
- env->npc = env->npc + 4;
-#endif
- break;
- case 0x83: /* flush windows */
-#ifdef TARGET_ABI32
- case 0x103:
-#endif
- flush_windows(env);
- /* next instruction */
- env->pc = env->npc;
- env->npc = env->npc + 4;
- break;
-#ifndef TARGET_SPARC64
- case TT_WIN_OVF: /* window overflow */
- save_window(env);
- break;
- case TT_WIN_UNF: /* window underflow */
- restore_window(env);
- break;
- case TT_TFAULT:
- case TT_DFAULT:
- break;
-#else
- case TT_SPILL: /* window overflow */
- save_window(env);
- break;
- case TT_FILL: /* window underflow */
- restore_window(env);
- break;
- case TT_TFAULT:
- case TT_DFAULT:
- break;
-#endif
- case EXCP_INTERRUPT:
- /* just indicate that signals should be handled asap */
- break;
- case EXCP_DEBUG:
- {
- gdb_handlesig(cs, TARGET_SIGTRAP);
- }
- break;
- default:
-#ifdef TARGET_SPARC64
- badtrap:
-#endif
- printf("Unhandled trap: 0x%x\n", trapnr);
- cpu_dump_state(cs, stderr, 0);
- exit(1);
- }
- process_pending_signals(env);
- }
-}
-
-#endif
-
static void usage(void)
{
printf("qemu-" TARGET_NAME " version " QEMU_FULL_VERSION
#else
cpu_model = "qemu32";
#endif
-#elif defined(TARGET_SPARC)
-#ifdef TARGET_SPARC64
- cpu_model = "TI UltraSparc II";
-#else
- cpu_model = "Fujitsu MB86904";
-#endif
#else
cpu_model = "any";
#endif
}
cpu = cpu_create(cpu_type);
env = cpu->env_ptr;
-#if defined(TARGET_SPARC) || defined(TARGET_PPC)
cpu_reset(cpu);
-#endif
thread_cpu = cpu;
if (getenv("QEMU_STRACE")) {
cpu_x86_load_seg(env, R_FS, 0);
cpu_x86_load_seg(env, R_GS, 0);
#endif
-#elif defined(TARGET_SPARC)
- {
- int i;
- env->pc = regs->pc;
- env->npc = regs->npc;
- env->y = regs->y;
- for (i = 0; i < 8; i++) {
- env->gregs[i] = regs->u_regs[i];
- }
- for (i = 0; i < 8; i++) {
- env->regwptr[i] = regs->u_regs[i + 8];
- }
- }
#else
#error unsupported target CPU
#endif
+++ /dev/null
-/*
- * SPARC sysarch() system call emulation
- *
- * Copyright (c) 2013 Stacey D. Son
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef BSD_USER_ARCH_SYSARCH_H_
-#define BSD_USER_ARCH_SYSARCH_H_
-
-#include "target_syscall.h"
-
-static inline abi_long do_freebsd_arch_sysarch(void *env, int op,
- abi_ulong parms)
-{
- int ret = 0;
-
- switch (op) {
- case TARGET_SPARC_SIGTRAMP_INSTALL:
- /* XXX not currently handled */
- case TARGET_SPARC_UTRAP_INSTALL:
- /* XXX not currently handled */
- default:
- ret = -TARGET_EINVAL;
- break;
- }
-
- return ret;
-}
-
-static inline void do_freebsd_arch_print_sysarch(
- const struct syscallname *name, abi_long arg1, abi_long arg2,
- abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6)
-{
-
- gemu_log("%s(%d, " TARGET_ABI_FMT_lx ", " TARGET_ABI_FMT_lx ", "
- TARGET_ABI_FMT_lx ")", name->name, (int)arg1, arg2, arg3, arg4);
-}
-
-#endif /*!BSD_USER_ARCH_SYSARCH_H_ */
+++ /dev/null
-/*
- * SPARC64 sysarch() system call emulation
- *
- * Copyright (c) 2013 Stacey D. Son
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef BSD_USER_ARCH_SYSARCH_H_
-#define BSD_USER_ARCH_SYSARCH_H_
-
-#include "target_syscall.h"
-
-static inline abi_long do_freebsd_arch_sysarch(void *env, int op,
- abi_ulong parms)
-{
- int ret = 0;
-
- switch (op) {
- case TARGET_SPARC_SIGTRAMP_INSTALL:
- /* XXX not currently handled */
- case TARGET_SPARC_UTRAP_INSTALL:
- /* XXX not currently handled */
- default:
- ret = -TARGET_EINVAL;
- break;
- }
-
- return ret;
-}
-
-static inline void do_freebsd_arch_print_sysarch(
- const struct syscallname *name, abi_long arg1, abi_long arg2,
- abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6)
-{
-
- gemu_log("%s(%d, " TARGET_ABI_FMT_lx ", " TARGET_ABI_FMT_lx ", "
- TARGET_ABI_FMT_lx ")", name->name, (int)arg1, arg2, arg3, arg4);
-}
-
-#endif /*!BSD_USER_ARCH_SYSARCH_H_ */