From patchwork Mon Sep 1 07:53:19 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 36336 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pa0-f69.google.com (mail-pa0-f69.google.com [209.85.220.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 93FA720792 for ; Mon, 1 Sep 2014 07:56:37 +0000 (UTC) Received: by mail-pa0-f69.google.com with SMTP id kx10sf60851551pab.8 for ; Mon, 01 Sep 2014 00:56:36 -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=XCgQT7fo3b58wbqBskKkk7AkVVfz+HiQjx3ofDh5t1E=; b=RlNleBGSuRpNUUn3BQTyb4Le1llKjXCMqZQido9FUXYa5rSto+PLZWbQmFji7Brcmg sLQ9PTvuRNMdf60GNSuOY9zDwEUmbatM1J/5BC6y+fteVENFh61pHH2RInmtHXKdiZmL HqC0t92bcC33eEpuVjCnS78T7fdxeWufTiPoWK1Gdl2VKyPbENOL9UAUlsyC8rL0ZY2b A0yuJILbohBFWqTmyE2n5lJdhkNQ0Rm8KT3oNfETxlbZ0zH4t58pCfNPx4rsXf4A6rNn 0ykDKKWLyGSC1AVMn2TmQjtINkvcq3z2ILYBH92C9Oyhz31CYvQVml3USW9po+l0Juji YpSA== X-Gm-Message-State: ALoCoQltE9n9fKmbSfQCM/XyvIctTeQqE6EADNGvtXp6VdofL+mVAxEMkve8l73QzOYhHUq/0cWD X-Received: by 10.69.29.234 with SMTP id jz10mr14956516pbd.1.1409558196907; Mon, 01 Sep 2014 00:56:36 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.108.38 with SMTP id i35ls1896869qgf.76.gmail; Mon, 01 Sep 2014 00:56:36 -0700 (PDT) X-Received: by 10.220.49.10 with SMTP id t10mr21909931vcf.34.1409558196816; Mon, 01 Sep 2014 00:56:36 -0700 (PDT) Received: from mail-vc0-f177.google.com (mail-vc0-f177.google.com [209.85.220.177]) by mx.google.com with ESMTPS id nv6si17857vcb.47.2014.09.01.00.56.36 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 01 Sep 2014 00:56:36 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.177 as permitted sender) client-ip=209.85.220.177; Received: by mail-vc0-f177.google.com with SMTP id hq11so5134122vcb.36 for ; Mon, 01 Sep 2014 00:56:36 -0700 (PDT) X-Received: by 10.52.146.17 with SMTP id sy17mr20181515vdb.29.1409558196717; Mon, 01 Sep 2014 00:56:36 -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.221.45.67 with SMTP id uj3csp350336vcb; Mon, 1 Sep 2014 00:56:36 -0700 (PDT) X-Received: by 10.140.23.40 with SMTP id 37mr18610138qgo.30.1409558196251; Mon, 01 Sep 2014 00:56:36 -0700 (PDT) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id z5si53998qcg.43.2014.09.01.00.56.36 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 01 Sep 2014 00:56:36 -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]:52625 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XOMTb-0005mF-Rf for patch@linaro.org; Mon, 01 Sep 2014 03:56:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51705) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XOMQj-0001GG-GQ for qemu-devel@nongnu.org; Mon, 01 Sep 2014 03:53:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XOMQd-0006nV-HC for qemu-devel@nongnu.org; Mon, 01 Sep 2014 03:53:37 -0400 Received: from mail-we0-f178.google.com ([74.125.82.178]:42381) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XOMQd-0006nL-7r for qemu-devel@nongnu.org; Mon, 01 Sep 2014 03:53:31 -0400 Received: by mail-we0-f178.google.com with SMTP id u57so5039232wes.9 for ; Mon, 01 Sep 2014 00:53:30 -0700 (PDT) X-Received: by 10.180.78.100 with SMTP id a4mr19681490wix.36.1409558010482; Mon, 01 Sep 2014 00:53:30 -0700 (PDT) Received: from ards-macbook-pro.local (cag06-7-83-153-85-71.fbx.proxad.net. [83.153.85.71]) by mx.google.com with ESMTPSA id gh1sm23183323wib.18.2014.09.01.00.53.29 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 01 Sep 2014 00:53:29 -0700 (PDT) From: Ard Biesheuvel To: qemu-devel@nongnu.org, peter.maydell@linaro.org, rob.herring@linaro.org Date: Mon, 1 Sep 2014 09:53:19 +0200 Message-Id: <1409558001-12148-4-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1409558001-12148-1-git-send-email-ard.biesheuvel@linaro.org> References: <1409558001-12148-1-git-send-email-ard.biesheuvel@linaro.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 74.125.82.178 Cc: Ard Biesheuvel Subject: [Qemu-devel] [PATCH 3/5] 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-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: ard.biesheuvel@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.177 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org 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 Signed-off-by: Ard Biesheuvel --- target-arm/cpu-qom.h | 3 +++ target-arm/cpu.h | 2 ++ target-arm/helper-a64.c | 11 +++++++++++ target-arm/helper.c | 21 +++++++++++++++++++++ target-arm/internals.h | 15 +++++++++++++++ target-arm/translate-a64.c | 26 +++++++++++++++++--------- target-arm/translate.c | 24 +++++++++++++++++------- 7 files changed, 86 insertions(+), 16 deletions(-) diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h index f71f6a4ccc6b..bcdd1e0edb55 100644 --- a/target-arm/cpu-qom.h +++ b/target-arm/cpu-qom.h @@ -191,6 +191,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 5fa91b4f1d6c..4c336b342553 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 2e9ef64786ae..54700e729711 100644 --- a/target-arm/helper-a64.c +++ b/target-arm/helper-a64.c @@ -483,6 +483,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 2b95f33872cb..3e29d08ae182 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -3497,6 +3497,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) { @@ -3599,6 +3609,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 53c2e3cf3e7e..37fd740526a2 100644 --- a/target-arm/internals.h +++ b/target-arm/internals.h @@ -210,6 +210,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 8e66b6c97282..9fd204694e7a 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -1473,20 +1473,28 @@ static void disas_exc(DisasContext *s, uint32_t insn) switch (opc) { case 0: - /* 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); - break; - } /* For SVC, HVC and SMC we advance the single-step state * machine before taking the exception. This is architecturally * mandated, to ensure that single-stepping a system call * instruction works properly. */ - gen_ss_advance(s); - gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16)); + switch (op2_ll) { + case 1: + gen_ss_advance(s); + gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16)); + break; + case 2: + gen_ss_advance(s); + gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_smc(imm16)); + break; + case 3: + gen_ss_advance(s); + gen_exception_insn(s, 0, EXCP_SMC, syn_aa64_hvc(imm16)); + break; + default: + unallocated_encoding(s); + break; + } break; case 1: if (op2_ll != 0) { diff --git a/target-arm/translate.c b/target-arm/translate.c index 2c0b1deaea81..3bef34264298 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -7871,9 +7871,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; } @@ -9709,10 +9714,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) {