From patchwork Fri May 23 02:30:06 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Herring X-Patchwork-Id: 30672 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-yk0-f200.google.com (mail-yk0-f200.google.com [209.85.160.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 5DD1C20369 for ; Fri, 23 May 2014 02:59:50 +0000 (UTC) Received: by mail-yk0-f200.google.com with SMTP id q9sf9583087ykb.3 for ; Thu, 22 May 2014 19:59:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:date :message-id:in-reply-to:references:cc:subject:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:list-subscribe :errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=F7OlxtVIeKHdaC5BxcigRQ4yrFD+cjcJnzAjVvcrOHg=; b=VjlMC9DLEsGjv4LWm46H4i550sg57BlC5fkGN+cI+z/UkFyHVAvIS7wlmIG7SXuqp5 f4Q22xDM3fEfiS8IQJLnoVjdKlUZZQ95L4ihqkAW4RbrdI4oSRDFJ87kjj7LJN6maiPp VlGPk9xBAMBo7vWKpnNHMt3uJZnWc/HzvTztgLWIKuPbFBuij2u3HhCSGp+X6yn+WCFF 3iKEv0lQ1per20PAFazIH2MIDpXMFlOWYJc0K8t/h6HY91fL3fG59JMgrfYIoLUglOZD AlDY3Tlq5m2lc9aslYDsnChcFXlWLgWegdFYINQy5UQ0IHQ+0/2mrtGjPQ9mD1GVuzri QMAA== X-Gm-Message-State: ALoCoQlyqHLmNTbG+zEmsztynuDIx683BO9MNaZL0EGnRYyzfDArLjMBjqj2r3adC87X3WOL1b0C X-Received: by 10.236.133.201 with SMTP id q49mr859942yhi.1.1400813990128; Thu, 22 May 2014 19:59:50 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.81.115 with SMTP id e106ls1558470qgd.65.gmail; Thu, 22 May 2014 19:59:50 -0700 (PDT) X-Received: by 10.220.249.198 with SMTP id ml6mr694970vcb.36.1400813989989; Thu, 22 May 2014 19:59:49 -0700 (PDT) Received: from mail-ve0-x236.google.com (mail-ve0-x236.google.com [2607:f8b0:400c:c01::236]) by mx.google.com with ESMTPS id up9si932706vec.97.2014.05.22.19.59.49 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 22 May 2014 19:59:49 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2607:f8b0:400c:c01::236 as permitted sender) client-ip=2607:f8b0:400c:c01::236; Received: by mail-ve0-f182.google.com with SMTP id sa20so5643036veb.27 for ; Thu, 22 May 2014 19:59:49 -0700 (PDT) X-Received: by 10.58.198.107 with SMTP id jb11mr1669501vec.10.1400813989909; Thu, 22 May 2014 19:59:49 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.221.72 with SMTP id ib8csp249051vcb; Thu, 22 May 2014 19:59:49 -0700 (PDT) X-Received: by 10.224.103.66 with SMTP id j2mr2402379qao.15.1400813989247; Thu, 22 May 2014 19:59:49 -0700 (PDT) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id f66si1972210qgf.93.2014.05.22.19.59.49 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 22 May 2014 19:59:49 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Received: from localhost ([::1]:40642 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WnfJD-0000jV-CP for patch@linaro.org; Thu, 22 May 2014 22:34:11 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33783) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WnfG1-00048B-2g for qemu-devel@nongnu.org; Thu, 22 May 2014 22:31:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WnfFc-0003o5-09 for qemu-devel@nongnu.org; Thu, 22 May 2014 22:30:52 -0400 Received: from mail-ob0-x234.google.com ([2607:f8b0:4003:c01::234]:49998) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WnfFb-0003nm-Dv for qemu-devel@nongnu.org; Thu, 22 May 2014 22:30:27 -0400 Received: by mail-ob0-f180.google.com with SMTP id va2so4771829obc.39 for ; Thu, 22 May 2014 19:30:26 -0700 (PDT) X-Received: by 10.182.43.132 with SMTP id w4mr1506007obl.41.1400812226924; Thu, 22 May 2014 19:30:26 -0700 (PDT) Received: from localhost.localdomain (66-90-144-10.dyn.grandenetworks.net. [66.90.144.10]) by mx.google.com with ESMTPSA id fm8sm5542727oeb.10.2014.05.22.19.30.26 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 22 May 2014 19:30:26 -0700 (PDT) From: Rob Herring To: Peter Maydell Date: Thu, 22 May 2014 21:30:06 -0500 Message-Id: <1400812209-26743-4-git-send-email-robherring2@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1400812209-26743-1-git-send-email-robherring2@gmail.com> References: <1400812209-26743-1-git-send-email-robherring2@gmail.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4003:c01::234 Cc: Rob Herring , Peter Crosthwaite , qemu-devel@nongnu.org, Christoffer Dall Subject: [Qemu-devel] [PATCH v2 3/6] target-arm: add hvc and smc exception emulation handling infrastructure X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org X-Original-Sender: robherring2@gmail.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2607:f8b0:400c:c01::236 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org; dkim=fail header.i=@gmail.com; dmarc=fail (p=NONE dis=NONE) header.from=gmail.com Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 From: Rob Herring Add the infrastructure to handle and emulate hvc and smc exceptions. This will enable emulation of things such as PSCI calls. This commit does not change the behavior and will exit with unknown exception. Signed-off-by: Rob Herring Reviewed-by: Peter Maydell --- v2: - add syn_aa32_smc - add missing syndrome calls - properly handle unhandled SMC/HVC emulation as undefined instruction exception - Move PSCI bits in arm_cpu_do_hvc/smc to next patch - fix immediate value for thumb hvc target-arm/cpu-qom.h | 3 +++ target-arm/cpu.h | 2 ++ target-arm/helper-a64.c | 32 ++++++++++++++++++++++++++++---- target-arm/helper.c | 30 ++++++++++++++++++++++++++++++ target-arm/internals.h | 20 ++++++++++++++++++++ target-arm/translate-a64.c | 13 ++++++++++--- target-arm/translate.c | 24 +++++++++++++++++------- 7 files changed, 110 insertions(+), 14 deletions(-) -- 1.9.1 diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index f835900..d2ff087 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -195,6 +195,9 @@ extern const struct VMStateDescription vmstate_arm_cpu; void register_cp_regs_for_features(ARMCPU *cpu); void init_cpreg_list(ARMCPU *cpu); +bool arm_cpu_do_hvc(CPUState *cs); +bool arm_cpu_do_smc(CPUState *cs); + void arm_cpu_do_interrupt(CPUState *cpu); void arm_v7m_cpu_do_interrupt(CPUState *cpu); diff --git a/target-arm/cpu.h b/target-arm/cpu.h index c83f249..905ba02 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -51,6 +51,8 @@ #define EXCP_EXCEPTION_EXIT 8 /* Return from v7M exception. */ #define EXCP_KERNEL_TRAP 9 /* Jumped to kernel code page. */ #define EXCP_STREX 10 +#define EXCP_HVC 11 +#define EXCP_SMC 12 #define ARMV7M_EXCP_RESET 1 #define ARMV7M_EXCP_NMI 2 diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c index 84411b4..e3dcca8 100644 --- a/target-arm/helper-a64.c +++ b/target-arm/helper-a64.c @@ -466,14 +466,11 @@ void aarch64_cpu_do_interrupt(CPUState *cs) env->exception.syndrome); } - env->cp15.esr_el1 = env->exception.syndrome; - env->cp15.far_el1 = env->exception.vaddress; - switch (cs->exception_index) { case EXCP_PREFETCH_ABORT: case EXCP_DATA_ABORT: qemu_log_mask(CPU_LOG_INT, "...with FAR 0x%" PRIx64 "\n", - env->cp15.far_el1); + env->exception.vaddress); break; case EXCP_BKPT: case EXCP_UDEF: @@ -485,10 +482,37 @@ void aarch64_cpu_do_interrupt(CPUState *cs) case EXCP_FIQ: addr += 0x100; break; + case EXCP_HVC: + if (arm_cpu_do_hvc(cs)) { + return; + } + qemu_log_mask(LOG_GUEST_ERROR, "Unhandled HVC exception\n"); + env->exception.syndrome = syn_uncategorized(); + if (is_a64(env)) { + env->pc -= 4; + } else { + env->regs[15] -= 4; + } + break; + case EXCP_SMC: + if (arm_cpu_do_smc(cs)) { + return; + } + qemu_log_mask(LOG_GUEST_ERROR, "Unhandled SMC exception\n"); + env->exception.syndrome = syn_uncategorized(); + if (is_a64(env)) { + env->pc -= 4; + } else { + env->regs[15] -= 4; + } + break; default: cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index); } + env->cp15.esr_el1 = env->exception.syndrome; + env->cp15.far_el1 = env->exception.vaddress; + if (is_a64(env)) { env->banked_spsr[0] = pstate_read(env); env->sp_el[arm_current_pl(env)] = env->xregs[31]; diff --git a/target-arm/helper.c b/target-arm/helper.c index 1307473..552e601 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -3255,6 +3255,16 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) env->thumb = addr & 1; } +bool arm_cpu_do_hvc(CPUState *cs) +{ + return false; +} + +bool arm_cpu_do_smc(CPUState *cs) +{ + return false; +} + /* Handle a CPU exception. */ void arm_cpu_do_interrupt(CPUState *cs) { @@ -3357,6 +3367,26 @@ void arm_cpu_do_interrupt(CPUState *cs) mask = CPSR_A | CPSR_I | CPSR_F; offset = 4; break; + case EXCP_HVC: + if (arm_cpu_do_hvc(cs)) { + return; + } + qemu_log_mask(LOG_GUEST_ERROR, "Unhandled HVC exception\n"); + new_mode = ARM_CPU_MODE_UND; + addr = 0x04; + mask = CPSR_A | CPSR_I; + offset = 4; + break; + case EXCP_SMC: + if (arm_cpu_do_smc(cs)) { + return; + } + qemu_log_mask(LOG_GUEST_ERROR, "Unhandled SMC exception\n"); + new_mode = ARM_CPU_MODE_UND; + addr = 0x04; + mask = CPSR_A | CPSR_I; + offset = 4; + break; default: cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index); return; /* Never happens. Keep compiler happy. */ diff --git a/target-arm/internals.h b/target-arm/internals.h index d63a975..52a284f 100644 --- a/target-arm/internals.h +++ b/target-arm/internals.h @@ -184,6 +184,26 @@ static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_thumb) | (is_thumb ? 0 : ARM_EL_IL); } +static inline uint32_t syn_aa64_hvc(uint32_t imm16) +{ + return (EC_AA64_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff); +} + +static inline uint32_t syn_aa32_hvc(uint32_t imm16) +{ + return (EC_AA32_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff); +} + +static inline uint32_t syn_aa64_smc(uint32_t imm16) +{ + return (EC_AA64_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff); +} + +static inline uint32_t syn_aa32_smc(void) +{ + return (EC_AA32_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL; +} + static inline uint32_t syn_aa64_bkpt(uint32_t imm16) { return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff); diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index b62db4d..d5e3624 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -1449,11 +1449,18 @@ static void disas_exc(DisasContext *s, uint32_t insn) /* SVC, HVC, SMC; since we don't support the Virtualization * or TrustZone extensions these all UNDEF except SVC. */ - if (op2_ll != 1) { - unallocated_encoding(s); + switch (op2_ll) { + case 1: + gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16)); + break; + case 2: + gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16)); + break; + case 3: + gen_exception_insn(s, 0, EXCP_SMC, syn_aa64_smc(imm16)); break; } - gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16)); + unallocated_encoding(s); break; case 1: if (op2_ll != 0) { diff --git a/target-arm/translate.c b/target-arm/translate.c index a4d920b..c108bc7 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -7727,9 +7727,14 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s) case 7: { int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4); - /* SMC instruction (op1 == 3) - and undefined instructions (op1 == 0 || op1 == 2) - will trap */ + /* HVC and SMC instructions */ + if (op1 == 2) { + gen_exception_insn(s, 0, EXCP_HVC, syn_aa32_hvc(imm16)); + break; + } else if (op1 == 3) { + gen_exception_insn(s, 0, EXCP_SMC, syn_aa32_smc()); + break; + } if (op1 != 1) { goto illegal_op; } @@ -9555,10 +9560,15 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw goto illegal_op; if (insn & (1 << 26)) { - /* Secure monitor call (v6Z) */ - qemu_log_mask(LOG_UNIMP, - "arm: unimplemented secure monitor call\n"); - goto illegal_op; /* not implemented. */ + if (!(insn & (1 << 20))) { + /* Hypervisor call (v7) */ + uint32_t imm16 = extract32(insn, 0, 12); + imm16 |= extract32(insn, 16, 4) << 12; + gen_exception_insn(s, 0, EXCP_HVC, syn_aa32_hvc(imm16)); + } else { + /* Secure monitor call (v6+) */ + gen_exception_insn(s, 0, EXCP_SMC, syn_aa32_smc()); + } } else { op = (insn >> 20) & 7; switch (op) {