From patchwork Sat Dec 5 11:44:21 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 40397 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 40A78B7BDF for ; Sat, 5 Dec 2009 23:09:10 +1100 (EST) Received: from localhost ([127.0.0.1]:46011 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NGtRj-0005Ex-4E for incoming@patchwork.ozlabs.org; Sat, 05 Dec 2009 07:09:07 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NGt48-0004Ai-68 for qemu-devel@nongnu.org; Sat, 05 Dec 2009 06:44:44 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NGt3z-00044a-4G for qemu-devel@nongnu.org; Sat, 05 Dec 2009 06:44:41 -0500 Received: from [199.232.76.173] (port=49816 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NGt3y-00043z-Jm for qemu-devel@nongnu.org; Sat, 05 Dec 2009 06:44:34 -0500 Received: from cantor2.suse.de ([195.135.220.15]:36005 helo=mx2.suse.de) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NGt3x-0008G0-Av for qemu-devel@nongnu.org; Sat, 05 Dec 2009 06:44:34 -0500 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) by mx2.suse.de (Postfix) with ESMTP id 0E11887567; Sat, 5 Dec 2009 12:44:32 +0100 (CET) From: Alexander Graf To: qemu-devel@nongnu.org Date: Sat, 5 Dec 2009 12:44:21 +0100 Message-Id: <1260013471-18691-2-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1260013471-18691-1-git-send-email-agraf@suse.de> References: <1260013471-18691-1-git-send-email-agraf@suse.de> X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.4-2.6 Cc: Carsten Otte , Aurelien Jarno Subject: [Qemu-devel] [PATCH 01/11] S/390 CPU fake emulation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Because Qemu currently requires a TCG target to exist and there are quite some useful helpers here to lay the groundwork for out KVM target, let's create a stub TCG emulation target for S390X CPUs. This is required to make tcg happy. The emulation target itself won't work though. Signed-off-by: Alexander Graf --- v5 -> v6: - add comment for asce register requirement - move cpu_get_phys_page_debug - coding style --- cpu-exec.c | 2 + target-s390x/cpu.h | 122 ++++++++++++++++++++++++++++++++++++++++++++++ target-s390x/exec.h | 51 +++++++++++++++++++ target-s390x/helper.c | 62 +++++++++++++++++++++++ target-s390x/op_helper.c | 74 ++++++++++++++++++++++++++++ target-s390x/translate.c | 63 ++++++++++++++++++++++++ 6 files changed, 374 insertions(+), 0 deletions(-) create mode 100644 target-s390x/cpu.h create mode 100644 target-s390x/exec.h create mode 100644 target-s390x/helper.c create mode 100644 target-s390x/op_helper.c create mode 100644 target-s390x/translate.c diff --git a/cpu-exec.c b/cpu-exec.c index 2c0765c..af4595b 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -249,6 +249,7 @@ int cpu_exec(CPUState *env1) #elif defined(TARGET_MIPS) #elif defined(TARGET_SH4) #elif defined(TARGET_CRIS) +#elif defined(TARGET_S390X) /* XXXXX */ #else #error unsupported target CPU @@ -673,6 +674,7 @@ int cpu_exec(CPUState *env1) #elif defined(TARGET_SH4) #elif defined(TARGET_ALPHA) #elif defined(TARGET_CRIS) +#elif defined(TARGET_S390X) /* XXXXX */ #else #error unsupported target CPU diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h new file mode 100644 index 0000000..9b10518 --- /dev/null +++ b/target-s390x/cpu.h @@ -0,0 +1,122 @@ +/* + * S/390 virtual CPU header + * + * Copyright (c) 2009 Ulrich Hecht + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA + */ +#ifndef CPU_S390X_H +#define CPU_S390X_H + +#define TARGET_LONG_BITS 64 + +#define ELF_MACHINE EM_S390 + +#define CPUState struct CPUS390XState + +#include "cpu-defs.h" + +#include "softfloat.h" + +#define NB_MMU_MODES 2 // guess +#define MMU_USER_IDX 0 // guess + +typedef union FPReg { + struct { +#ifdef WORDS_BIGENDIAN + float32 e; + int32_t __pad; +#else + int32_t __pad; + float32 e; +#endif + }; + float64 d; + uint64_t i; +} FPReg; + +typedef struct CPUS390XState { + uint64_t regs[16]; /* GP registers */ + + uint32_t aregs[16]; /* access registers */ + + uint32_t fpc; /* floating-point control register */ + FPReg fregs[16]; /* FP registers */ + float_status fpu_status; /* passed to softfloat lib */ + + struct { + uint64_t mask; + uint64_t addr; + } psw; + + int cc; /* condition code (0-3) */ + + uint64_t __excp_addr; + + CPU_COMMON +} CPUS390XState; + +#if defined(CONFIG_USER_ONLY) +static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) +{ + if (newsp) + env->regs[15] = newsp; + env->regs[0] = 0; +} +#endif + +CPUS390XState *cpu_s390x_init(const char *cpu_model); +int cpu_s390x_exec(CPUS390XState *s); +void cpu_s390x_close(CPUS390XState *s); + +/* you can call this signal handler from your SIGBUS and SIGSEGV + signal handlers to inform the virtual CPU of exceptions. non zero + is returned if the signal was handled by the virtual CPU. */ +int cpu_s390x_signal_handler(int host_signum, void *pinfo, + void *puc); +int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw, + int mmu_idx, int is_softmuu); +#define cpu_handle_mmu_fault cpu_s390x_handle_mmu_fault + +#define TARGET_PAGE_BITS 12 + +#define cpu_init cpu_s390x_init +#define cpu_exec cpu_s390x_exec +#define cpu_gen_code cpu_s390x_gen_code + +#include "cpu-all.h" +#include "exec-all.h" + +#define EXCP_OPEX 1 /* operation exception (sigill) */ +#define EXCP_SVC 2 /* supervisor call (syscall) */ +#define EXCP_ADDR 5 /* addressing exception */ +#define EXCP_EXECUTE_SVC 0xff00000 /* supervisor call via execute insn */ + +static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock* tb) +{ + env->psw.addr = tb->pc; +} + +static inline void cpu_get_tb_cpu_state(CPUState* env, target_ulong *pc, + target_ulong *cs_base, int *flags) +{ + *pc = env->psw.addr; + /* XXX this is correct for user-mode emulation, but needs + * the asce register information as well when softmmu + * is implemented in the future */ + *cs_base = 0; + *flags = env->psw.mask; +} +#endif diff --git a/target-s390x/exec.h b/target-s390x/exec.h new file mode 100644 index 0000000..5198359 --- /dev/null +++ b/target-s390x/exec.h @@ -0,0 +1,51 @@ +/* + * S/390 execution defines + * + * Copyright (c) 2009 Ulrich Hecht + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA + */ + +#include "dyngen-exec.h" + +register struct CPUS390XState *env asm(AREG0); + +#include "cpu.h" +#include "exec-all.h" + +static inline int cpu_has_work(CPUState *env) +{ + return env->interrupt_request & CPU_INTERRUPT_HARD; // guess +} + +static inline void regs_to_env(void) +{ +} + +static inline void env_to_regs(void) +{ +} + +static inline int cpu_halted(CPUState *env) +{ + if (!env->halted) { + return 0; + } + if (cpu_has_work(env)) { + env->halted = 0; + return 0; + } + return EXCP_HALTED; +} diff --git a/target-s390x/helper.c b/target-s390x/helper.c new file mode 100644 index 0000000..4a198ae --- /dev/null +++ b/target-s390x/helper.c @@ -0,0 +1,62 @@ +/* + * S/390 helpers + * + * Copyright (c) 2009 Ulrich Hecht + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA + */ + +#include +#include +#include + +#include "cpu.h" +#include "exec-all.h" +#include "gdbstub.h" +#include "qemu-common.h" + +CPUS390XState *cpu_s390x_init(const char *cpu_model) +{ + CPUS390XState *env; + static int inited = 0; + + env = qemu_mallocz(sizeof(CPUS390XState)); + cpu_exec_init(env); + if (!inited) { + inited = 1; + } + + env->cpu_model_str = cpu_model; + cpu_reset(env); + qemu_init_vcpu(env); + return env; +} + +target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) +{ + return addr; +} + +void cpu_reset(CPUS390XState *env) +{ + if (qemu_loglevel_mask(CPU_LOG_RESET)) { + qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); + log_cpu_state(env, 0); + } + + memset(env, 0, offsetof(CPUS390XState, breakpoints)); + /* FIXME: reset vector? */ + tlb_flush(env, 1); +} diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c new file mode 100644 index 0000000..e623de9 --- /dev/null +++ b/target-s390x/op_helper.c @@ -0,0 +1,74 @@ +/* + * S/390 helper routines + * + * Copyright (c) 2009 Alexander Graf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA + */ + +#include "exec.h" + +/*****************************************************************************/ +/* Softmmu support */ +#if !defined (CONFIG_USER_ONLY) + +#define MMUSUFFIX _mmu + +#define SHIFT 0 +#include "softmmu_template.h" + +#define SHIFT 1 +#include "softmmu_template.h" + +#define SHIFT 2 +#include "softmmu_template.h" + +#define SHIFT 3 +#include "softmmu_template.h" + +/* try to fill the TLB and return an exception if error. If retaddr is + NULL, it means that the function was called in C code (i.e. not + from generated code or from helper.c) */ +/* XXX: fix it to restore all registers */ +void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) +{ + TranslationBlock *tb; + CPUState *saved_env; + unsigned long pc; + int ret; + + /* XXX: hack to restore env in all cases, even if not called from + generated code */ + saved_env = env; + env = cpu_single_env; + ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + if (unlikely(ret != 0)) { + if (likely(retaddr)) { + /* now we have a real cpu fault */ + pc = (unsigned long)retaddr; + tb = tb_find_pc(pc); + if (likely(tb)) { + /* the PC is inside the translated code. It means that we have + a virtual CPU fault */ + cpu_restore_state(tb, env, pc, NULL); + } + } + /* XXX */ + /* helper_raise_exception_err(env->exception_index, env->error_code); */ + } + env = saved_env; +} + +#endif diff --git a/target-s390x/translate.c b/target-s390x/translate.c new file mode 100644 index 0000000..cde19df --- /dev/null +++ b/target-s390x/translate.c @@ -0,0 +1,63 @@ +/* + * S/390 translation + * + * Copyright (c) 2009 Ulrich Hecht + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA + */ + +#include "cpu.h" +#include "exec-all.h" +#include "disas.h" +#include "tcg-op.h" +#include "qemu-log.h" + +void cpu_dump_state(CPUState *env, FILE *f, + int (*cpu_fprintf)(FILE *f, const char *fmt, ...), + int flags) +{ + int i; + for (i = 0; i < 16; i++) { + cpu_fprintf(f, "R%02d=%016lx", i, env->regs[i]); + if ((i % 4) == 3) { + cpu_fprintf(f, "\n"); + } else { + cpu_fprintf(f, " "); + } + } + for (i = 0; i < 16; i++) { + cpu_fprintf(f, "F%02d=%016lx", i, env->fregs[i]); + if ((i % 4) == 3) { + cpu_fprintf(f, "\n"); + } else { + cpu_fprintf(f, " "); + } + } + cpu_fprintf(f, "PSW=mask %016lx addr %016lx cc %02x\n", env->psw.mask, env->psw.addr, env->cc); +} + +void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb) +{ +} + +void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) +{ +} + +void gen_pc_load(CPUState *env, TranslationBlock *tb, + unsigned long searched_pc, int pc_pos, void *puc) +{ + env->psw.addr = gen_opc_pc[pc_pos]; +}