From patchwork Mon May 5 16:00:19 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Herring X-Patchwork-Id: 29656 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qc0-f199.google.com (mail-qc0-f199.google.com [209.85.216.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id C88882055D for ; Mon, 5 May 2014 16:05:23 +0000 (UTC) Received: by mail-qc0-f199.google.com with SMTP id i17sf17060820qcy.2 for ; Mon, 05 May 2014 09:05:23 -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=GdVW4B7FCh+rtkQmutK7b8zou+uM5QC1QVQMlfVXMY0=; b=X4GZZWI/N648e0Pa+j+ooxocdlaXKyvbVyncV7BlKgUCfdL3f99lcoWnFoN0IWS89o zrrhSx5Yf67YS9vv5FqpG25Q//9hwHO2fwv0RdB/hBdh+22DJ4C0HZzSEaIPoyxHRLqx 15bDXOc4FdLvZhkHQw6N0GbKS2/VMZy26y7za0mBxfDZK+G4B0Nf97FU7V3//PsLRJ3O Yrz6fpdUbEvzneJAAsCqXLx1Tvx9VVSjnYo7U76WR3bdV5K3wGwwBQFr1oj5mDfyORIF QUvV8n9dYHDDgQdtHs/MxRjWDnG0GVb0QE3Bl+Chq0QV1hmUXnoCow/BZYzhBfMz9T2p +PgQ== X-Gm-Message-State: ALoCoQk0Iz+rlKOaatalHF+6TkEYWKY9L8qo1thimg40zeKmndc3MPdG+evKJWfeThwMvQvw9Eom X-Received: by 10.58.18.200 with SMTP id y8mr16692700ved.20.1399305923418; Mon, 05 May 2014 09:05:23 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.82.145 with SMTP id h17ls2539267qgd.31.gmail; Mon, 05 May 2014 09:05:23 -0700 (PDT) X-Received: by 10.58.154.10 with SMTP id vk10mr29177621veb.18.1399305923140; Mon, 05 May 2014 09:05:23 -0700 (PDT) Received: from mail-vc0-x22d.google.com (mail-vc0-x22d.google.com [2607:f8b0:400c:c03::22d]) by mx.google.com with ESMTPS id s7si1693207vev.110.2014.05.05.09.05.23 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 05 May 2014 09:05:23 -0700 (PDT) Received-SPF: none (google.com: patch+caf_=patchwork-forward=linaro.org@linaro.org does not designate permitted sender hosts) client-ip=2607:f8b0:400c:c03::22d; Received: by mail-vc0-f173.google.com with SMTP id ik5so8841163vcb.18 for ; Mon, 05 May 2014 09:05:23 -0700 (PDT) X-Received: by 10.58.216.163 with SMTP id or3mr2145vec.80.1399305923025; Mon, 05 May 2014 09:05:23 -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 ib8csp152073vcb; Mon, 5 May 2014 09:05:22 -0700 (PDT) X-Received: by 10.140.88.241 with SMTP id t104mr42803241qgd.29.1399305922442; Mon, 05 May 2014 09:05:22 -0700 (PDT) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id j6si3670697qan.9.2014.05.05.09.05.22 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 05 May 2014 09:05:22 -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]:58301 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WhLOL-0004S3-VD for patch@linaro.org; Mon, 05 May 2014 12:05:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43036) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WhLJt-0006s8-73 for qemu-devel@nongnu.org; Mon, 05 May 2014 12:00:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WhLJn-0000lx-1u for qemu-devel@nongnu.org; Mon, 05 May 2014 12:00:45 -0400 Received: from mail-oa0-x22e.google.com ([2607:f8b0:4003:c02::22e]:43809) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WhLJm-0000lc-H8 for qemu-devel@nongnu.org; Mon, 05 May 2014 12:00:38 -0400 Received: by mail-oa0-f46.google.com with SMTP id i4so8012968oah.33 for ; Mon, 05 May 2014 09:00:37 -0700 (PDT) X-Received: by 10.60.62.34 with SMTP id v2mr34089485oer.37.1399305637901; Mon, 05 May 2014 09:00:37 -0700 (PDT) Received: from localhost.localdomain (72-48-77-163.dyn.grandenetworks.net. [72.48.77.163]) by mx.google.com with ESMTPSA id dw5sm20133189obb.0.2014.05.05.09.00.36 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 05 May 2014 09:00:37 -0700 (PDT) From: Rob Herring To: Peter Maydell Date: Mon, 5 May 2014 11:00:19 -0500 Message-Id: <1399305623-22016-4-git-send-email-robherring2@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1399305623-22016-1-git-send-email-robherring2@gmail.com> References: <1399305623-22016-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:c02::22e Cc: Rob Herring , qemu-devel@nongnu.org, Christoffer Dall Subject: [Qemu-devel] [PATCH 3/7] 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=neutral (google.com: patch+caf_=patchwork-forward=linaro.org@linaro.org does not designate permitted sender hosts) 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 --- target-arm/cpu-qom.h | 3 +++ target-arm/cpu.h | 2 ++ target-arm/helper-a64.c | 11 +++++++++++ target-arm/helper.c | 33 +++++++++++++++++++++++++++++++++ target-arm/internals.h | 15 +++++++++++++++ target-arm/translate-a64.c | 13 ++++++++++--- target-arm/translate.c | 24 +++++++++++++++++------- 7 files changed, 91 insertions(+), 10 deletions(-) diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index 8ccb227..88aaf6a 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -185,6 +185,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..d2c1097 100644 --- a/target-arm/helper-a64.c +++ b/target-arm/helper-a64.c @@ -485,6 +485,17 @@ void aarch64_cpu_do_interrupt(CPUState *cs) case EXCP_FIQ: addr += 0x100; break; + case EXCP_HVC: + if (arm_cpu_do_hvc(cs)) { + return; + } + cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index); + return; + case EXCP_SMC: + if (arm_cpu_do_smc(cs)) { + return; + } + /* Fall-though */ default: cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index); } diff --git a/target-arm/helper.c b/target-arm/helper.c index 3be917c..b5b4a17 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -3253,6 +3253,28 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) env->thumb = addr & 1; } +bool arm_cpu_do_hvc(CPUState *cs) +{ + bool ret; + + ret = arm_handle_psci(cs); + if (ret) { + return ret; + } + return false; +} + +bool arm_cpu_do_smc(CPUState *cs) +{ + bool ret; + + ret = arm_handle_psci(cs); + if (ret) { + return ret; + } + return false; +} + /* Handle a CPU exception. */ void arm_cpu_do_interrupt(CPUState *cs) { @@ -3355,6 +3377,17 @@ 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; + } + cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index); + return; + case EXCP_SMC: + if (arm_cpu_do_smc(cs)) { + return; + } + /* Fall-though */ 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..c71eabb 100644 --- a/target-arm/internals.h +++ b/target-arm/internals.h @@ -184,6 +184,21 @@ 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_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..fa49ed8 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_smc(imm16)); + break; + case 3: + gen_exception_insn(s, 0, EXCP_SMC, syn_aa64_hvc(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..13ece7f 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, imm16); + break; + } else if (op1 == 3) { + gen_exception_insn(s, 0, EXCP_SMC, 0); + 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, 16, 4); + imm16 |= extract32(insn, 0, 12) << 4; + gen_exception_insn(s, 0, EXCP_HVC, imm16); + } else { + /* Secure monitor call (v6+) */ + gen_exception_insn(s, 0, EXCP_SMC, 0); + } } else { op = (insn >> 20) & 7; switch (op) {