From patchwork Wed May 10 14:24:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhupinder Thakur X-Patchwork-Id: 98996 Delivered-To: patch@linaro.org Received: by 10.140.96.100 with SMTP id j91csp253165qge; Wed, 10 May 2017 07:29:12 -0700 (PDT) X-Received: by 10.36.175.5 with SMTP id t5mr1649545ite.80.1494426552442; Wed, 10 May 2017 07:29:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1494426552; cv=none; d=google.com; s=arc-20160816; b=lQ9pFjk6Femu1ztNVJDKh4bTdaHNoPkzRWn8ten3wfoNlEvUkmTGAfVeEAuSCYYIP9 ZkKb12rWpTwLriRh4Vek6u07kNBJMEBjZW5hjW6ee5FoOshjLhsCgrsZujPL0qtuyh9m BFj1rWPMDiof58fiVWDhHbh/r+KU8i7QO2CN8BGIfK6PmH3FwWbZHdjzEy6TveKmkZ/1 VqtksysiQMjQtCOXCvjrSN/WZWwhAg3CWPFvNkrFwiuOIvieQ+mUE0LOZ0XqPFAh1JGc ONlHQqIpdh4gfiYcn5gg0nB4X30mHNW8ic57bhx6nYH2aGxEUrhOWaTzNDqPBN+bCVhP rwiQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:cc:message-id:date:to:from:dkim-signature :arc-authentication-results; bh=NFamQUsFRjf+BYTeFCLGtRJRgekb3cdOuTfKczmA9+8=; b=YHgjvFXY9g+Op4bgEa46ZW4AN9h9YIRm6kyL7xkOG2Cf3QgXNdxunVLdiIqxl66IOQ jDo0lXUHEm8K/nm3HAg+Y+LLY/leUOHdNECOwweIZvUGW4TjuFtWmtbl7vGua79nBZXr rFVOPuvWDZGeb4Af8HlSz34B3KH5zCOpBqz245soaUjTTGZzUuOk+dSOr2QVByMnY/1Y NE+9PZVl9MqMVa2sNPQ5ntcxAMUb+qfuWk71aqT6BLuEa0RF36pI80z6u5yqF8KykHEs l2Je0ndAEK/0BR/Mfjj99VR3kbNWk/uKNdTxskMH968iIrXvfCnaE8BdBVlliNLj76aM o0uQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=neutral (google.com: 192.237.175.120 is neither permitted nor denied by best guess record for domain of xen-devel-bounces@lists.xen.org) smtp.mailfrom=xen-devel-bounces@lists.xen.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id l2si2169706ioa.19.2017.05.10.07.29.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 May 2017 07:29:12 -0700 (PDT) Received-SPF: neutral (google.com: 192.237.175.120 is neither permitted nor denied by best guess record for domain of xen-devel-bounces@lists.xen.org) client-ip=192.237.175.120; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=neutral (google.com: 192.237.175.120 is neither permitted nor denied by best guess record for domain of xen-devel-bounces@lists.xen.org) smtp.mailfrom=xen-devel-bounces@lists.xen.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d8Sa4-0002Ys-Ku; Wed, 10 May 2017 14:27:08 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d8Sa3-0002Yj-S3 for xen-devel@lists.xenproject.org; Wed, 10 May 2017 14:27:08 +0000 Received: from [193.109.254.147] by server-3.bemta-6.messagelabs.com id 4F/77-03058-B3323195; Wed, 10 May 2017 14:27:07 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupgkeJIrShJLcpLzFFi42Lxqg021bVSFo4 0mLxCyeL7lslMDowehz9cYQlgjGLNzEvKr0hgzVj19jdLwZLwirt717E2MK7R6GLk4hASmM4o cejDe1YQh0WgnVni6OpVYI6EwDsWiU1bTzJ1MXICOXES79bPYoWwKySW3ZrDBmILCWhJHD01m xViVBOTxLpzz4ESHBxsAiYSszokQGpEBJQk7q2aDDaHWSBU4t+zNnYQW1ggQuLT1yPMIDaLgK rEtvv9jCA2r4C3xOqXb9kgdslJ3DzXyTyBkW8BI8MqRo3i1KKy1CJdI0u9pKLM9IyS3MTMHF1 DAzO93NTi4sT01JzEpGK95PzcTYzAUGEAgh2MBxYFHmKU5GBSEuXV3SUUKcSXlJ9SmZFYnBFf VJqTWnyIUYaDQ0mC97+icKSQYFFqempFWmYOMGhh0hIcPEoivK9B0rzFBYm5xZnpEKlTjLocj 1b+eM8kxJKXn5cqJc7rqARUJABSlFGaBzcCFkGXGGWlhHkZgY4S4ilILcrNLEGVf8UozsGoJM z7G2QVT2ZeCdymV0BHMAEdEcggAHJESSJCSqqBsWRbj/7772y6oc7l1Ytk0mI2trzXrto99/0 Z4V33v05is9/9yfPT0mkyzS1yom/mO3ZtWDyv+ohX/vyE1hc+YYards/7/7NgQ9+ic3vNrzxN q5qSO+sp35PdjrY6/1eJ2uXEl2jauu4LWqr4VyH80blN/9a3HwpSDD93qbfh7i0ty/tzNHJVf iuxFGckGmoxFxUnAgC5BAAimwIAAA== X-Env-Sender: bhupinder.thakur@linaro.org X-Msg-Ref: server-15.tower-27.messagelabs.com!1494426425!48498322!1 X-Originating-IP: [74.125.83.53] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.4.12; banners=-,-,- X-VirusChecked: Checked Received: (qmail 5546 invoked from network); 10 May 2017 14:27:06 -0000 Received: from mail-pg0-f53.google.com (HELO mail-pg0-f53.google.com) (74.125.83.53) by server-15.tower-27.messagelabs.com with AES128-GCM-SHA256 encrypted SMTP; 10 May 2017 14:27:06 -0000 Received: by mail-pg0-f53.google.com with SMTP id o3so17552759pgn.2 for ; Wed, 10 May 2017 07:27:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=IGrbkDdkRhycryHarwtaF3ehGjbsa+VPScMKE2Zv3Es=; b=ZprNn+1KtCdKA2HhYXWqLQkv6IjVieWkRdsIS540uaGwyZNjow0h7UzPrvIUt2rA4o CVqVn0kbUDItlZMxf0stEXtRiiSpRkO9d7pgMjXOjLLjKvGZ4Fo0uu5zqEmGli0/uWxA h6Cibox4hqIWJzy1vPiHBnTGkj3g9VFClqxKA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=IGrbkDdkRhycryHarwtaF3ehGjbsa+VPScMKE2Zv3Es=; b=c+nyq/BQDOYQa5m4JMRxoWRNc3jPucKm8V2P473J3X4UmPD3MCmViVgIaxCgaF0Let yMPST0JpUsyZ7U8m8ttl5pAYN8DDZBVkK1SITKfgdBKHRx+2wEP0C+mmOG/e8zyLFdNT wgwWqDiLlVrjg6VzPzF3/suHdK/59kArKkUVvk4SoUXw0W/eewh/SAtjaJzyozKJ1e0G cC6jm4OYDisovki7smfXwVdJu2TsDsP8GeV6gq827YIvGz5B0ua5094MTKARRle4xLd2 1mjeuFDVYvYK4D1CQ0UaopDUm7kpnkk1d8F8KTQ56wFHC4QHJYMUrJLnPT667EqNtCPM QggQ== X-Gm-Message-State: AODbwcD5W9kL09VSrWIs5w6ev6yeO7lds7muL77G/DVmzyqLW7XFyWeg XsXTtM9lQA+rjGGJ X-Received: by 10.98.0.146 with SMTP id 140mr6480171pfa.172.1494426424877; Wed, 10 May 2017 07:27:04 -0700 (PDT) Received: from blr-ubuntu-linaro.wlan.qualcomm.com ([61.0.91.57]) by smtp.gmail.com with ESMTPSA id k79sm6432320pfj.6.2017.05.10.07.27.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 10 May 2017 07:27:04 -0700 (PDT) From: Bhupinder Thakur To: xen-devel@lists.xenproject.org Date: Wed, 10 May 2017 19:54:51 +0530 Message-Id: <1494426293-32481-1-git-send-email-bhupinder.thakur@linaro.org> X-Mailer: git-send-email 2.7.4 Cc: Julien Grall , Stefano Stabellini Subject: [Xen-devel] [PATCH 01/12 v3] xen/arm: vpl011: Move vgic register access functions to vreg.h X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" These functions are generic in nature and can be reused by other emulation code in Xen. One recent example is pl011 emulation, which needs similar funictions to read/write the registers. This patch moves the register access function definitions from vgic.h to vreg.h. Signed-off-by: Bhupinder Thakur --- xen/include/asm-arm/vgic.h | 99 +--------------------------------------------- xen/include/asm-arm/vreg.h | 98 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 98 deletions(-) diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h index 544867a..c838298 100644 --- a/xen/include/asm-arm/vgic.h +++ b/xen/include/asm-arm/vgic.h @@ -20,6 +20,7 @@ #include #include +#include struct pending_irq { @@ -171,104 +172,6 @@ static inline int REG_RANK_NR(int b, uint32_t n) } } -#define VGIC_REG_MASK(size) ((~0UL) >> (BITS_PER_LONG - ((1 << (size)) * 8))) - -/* - * The check on the size supported by the register has to be done by - * the caller of vgic_regN_*. - * - * vgic_reg_* should never be called directly. Instead use the vgic_regN_* - * according to size of the emulated register - * - * Note that the alignment fault will always be taken in the guest - * (see B3.12.7 DDI0406.b). - */ -static inline register_t vgic_reg_extract(unsigned long reg, - unsigned int offset, - enum dabt_size size) -{ - reg >>= 8 * offset; - reg &= VGIC_REG_MASK(size); - - return reg; -} - -static inline void vgic_reg_update(unsigned long *reg, register_t val, - unsigned int offset, - enum dabt_size size) -{ - unsigned long mask = VGIC_REG_MASK(size); - int shift = offset * 8; - - *reg &= ~(mask << shift); - *reg |= ((unsigned long)val & mask) << shift; -} - -static inline void vgic_reg_setbits(unsigned long *reg, register_t bits, - unsigned int offset, - enum dabt_size size) -{ - unsigned long mask = VGIC_REG_MASK(size); - int shift = offset * 8; - - *reg |= ((unsigned long)bits & mask) << shift; -} - -static inline void vgic_reg_clearbits(unsigned long *reg, register_t bits, - unsigned int offset, - enum dabt_size size) -{ - unsigned long mask = VGIC_REG_MASK(size); - int shift = offset * 8; - - *reg &= ~(((unsigned long)bits & mask) << shift); -} - -/* N-bit register helpers */ -#define VGIC_REG_HELPERS(sz, offmask) \ -static inline register_t vgic_reg##sz##_extract(uint##sz##_t reg, \ - const mmio_info_t *info)\ -{ \ - return vgic_reg_extract(reg, info->gpa & offmask, \ - info->dabt.size); \ -} \ - \ -static inline void vgic_reg##sz##_update(uint##sz##_t *reg, \ - register_t val, \ - const mmio_info_t *info) \ -{ \ - unsigned long tmp = *reg; \ - \ - vgic_reg_update(&tmp, val, info->gpa & offmask, \ - info->dabt.size); \ - \ - *reg = tmp; \ -} \ - \ -static inline void vgic_reg##sz##_setbits(uint##sz##_t *reg, \ - register_t bits, \ - const mmio_info_t *info) \ -{ \ - unsigned long tmp = *reg; \ - \ - vgic_reg_setbits(&tmp, bits, info->gpa & offmask, \ - info->dabt.size); \ - \ - *reg = tmp; \ -} \ - \ -static inline void vgic_reg##sz##_clearbits(uint##sz##_t *reg, \ - register_t bits, \ - const mmio_info_t *info) \ -{ \ - unsigned long tmp = *reg; \ - \ - vgic_reg_clearbits(&tmp, bits, info->gpa & offmask, \ - info->dabt.size); \ - \ - *reg = tmp; \ -} - /* * 64 bits registers are only supported on platform with 64-bit long. * This is also allow us to optimize the 32 bit case by using diff --git a/xen/include/asm-arm/vreg.h b/xen/include/asm-arm/vreg.h index ed2bd6f..1442c58 100644 --- a/xen/include/asm-arm/vreg.h +++ b/xen/include/asm-arm/vreg.h @@ -107,4 +107,102 @@ static inline bool vreg_emulate_sysreg64(struct cpu_user_regs *regs, union hsr h #endif +#define VGIC_REG_MASK(size) ((~0UL) >> (BITS_PER_LONG - ((1 << (size)) * 8))) + +/* + * The check on the size supported by the register has to be done by + * the caller of vgic_regN_*. + * + * vgic_reg_* should never be called directly. Instead use the vgic_regN_* + * according to size of the emulated register + * + * Note that the alignment fault will always be taken in the guest + * (see B3.12.7 DDI0406.b). + */ +static inline register_t vgic_reg_extract(unsigned long reg, + unsigned int offset, + enum dabt_size size) +{ + reg >>= 8 * offset; + reg &= VGIC_REG_MASK(size); + + return reg; +} + +static inline void vgic_reg_update(unsigned long *reg, register_t val, + unsigned int offset, + enum dabt_size size) +{ + unsigned long mask = VGIC_REG_MASK(size); + int shift = offset * 8; + + *reg &= ~(mask << shift); + *reg |= ((unsigned long)val & mask) << shift; +} + +static inline void vgic_reg_setbits(unsigned long *reg, register_t bits, + unsigned int offset, + enum dabt_size size) +{ + unsigned long mask = VGIC_REG_MASK(size); + int shift = offset * 8; + + *reg |= ((unsigned long)bits & mask) << shift; +} + +static inline void vgic_reg_clearbits(unsigned long *reg, register_t bits, + unsigned int offset, + enum dabt_size size) +{ + unsigned long mask = VGIC_REG_MASK(size); + int shift = offset * 8; + + *reg &= ~(((unsigned long)bits & mask) << shift); +} + +/* N-bit register helpers */ +#define VGIC_REG_HELPERS(sz, offmask) \ +static inline register_t vgic_reg##sz##_extract(uint##sz##_t reg, \ + const mmio_info_t *info)\ +{ \ + return vgic_reg_extract(reg, info->gpa & offmask, \ + info->dabt.size); \ +} \ + \ +static inline void vgic_reg##sz##_update(uint##sz##_t *reg, \ + register_t val, \ + const mmio_info_t *info) \ +{ \ + unsigned long tmp = *reg; \ + \ + vgic_reg_update(&tmp, val, info->gpa & offmask, \ + info->dabt.size); \ + \ + *reg = tmp; \ +} \ + \ +static inline void vgic_reg##sz##_setbits(uint##sz##_t *reg, \ + register_t bits, \ + const mmio_info_t *info) \ +{ \ + unsigned long tmp = *reg; \ + \ + vgic_reg_setbits(&tmp, bits, info->gpa & offmask, \ + info->dabt.size); \ + \ + *reg = tmp; \ +} \ + \ +static inline void vgic_reg##sz##_clearbits(uint##sz##_t *reg, \ + register_t bits, \ + const mmio_info_t *info) \ +{ \ + unsigned long tmp = *reg; \ + \ + vgic_reg_clearbits(&tmp, bits, info->gpa & offmask, \ + info->dabt.size); \ + \ + *reg = tmp; \ +} + #endif /* __ASM_ARM_VREG__ */ From patchwork Wed May 10 14:24:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhupinder Thakur X-Patchwork-Id: 98995 Delivered-To: patch@linaro.org Received: by 10.140.96.100 with SMTP id j91csp253141qge; Wed, 10 May 2017 07:29:10 -0700 (PDT) X-Received: by 10.107.39.206 with SMTP id n197mr3936435ion.114.1494426550236; Wed, 10 May 2017 07:29:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1494426550; cv=none; d=google.com; s=arc-20160816; b=obbZC0LgRFoof5poOHz5RPZrALviARp2WMrkONrKCQaxEcbvcQGKd2tOTYLHSVRu2j 5mq93SnTRovd7dMwYk3wtS/WluTRnWLTedNu6aUab/bZRDDxuezDK+0epNM8qPgA67bS E9Pa9NJg0ocShQQ59BNFboEFouvN8oUm1EQOgyTfMRghoYqWk14n4WTpk2fMI2wwf+Dq faWWCZtvHAS/jxHVF/cL9ULRRwARLRdUwYRLGJxwdJycXMnYVFBjCSVcoJqcqNL5sC9d pgbTAlfTq5K3tx+uGzecQA+A56LhsQmEIyVFVp+9EDWuaud2kc1aTd7WdGatebotA1St QLfw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:cc:references:in-reply-to:message-id:date:to :from:dkim-signature:arc-authentication-results; bh=SniBRhWbWbYF2A0zVomBJ+S1KPRKPl4h4sMxyhR1jFw=; b=Bbl7z5ZBXtEGjjNPcpp06qGFExUlG/Y/i7VIbKqk/W1UQZWb4wTnbQSKbwWLd65lWv 0my/5Nah76rC7S0VimtmS7yJ34Bkzf2lAm6wWX9/gu40ZPbIZfKKhYfVCt+eoltYcj8S uTZGdl38UbmSXoH/ZZdvciUipTtPrhHEOJKugPlaf9ihm4rfzrpCQTrVPU1ok2NJTgOE Mqp073f63FFXZ97KqGuRL7WXYsI5ZzrovsALVGW9e/cUyKdVi+SWvbNbyXcfqfpj4ETe ryJKbXxXmpuWMLyY7OaS3knx3+KJbrmUZo8/zIgSWEwwW9PsmqjjBCE7XUiafWaiH3O6 1r8Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=neutral (google.com: 192.237.175.120 is neither permitted nor denied by best guess record for domain of xen-devel-bounces@lists.xen.org) smtp.mailfrom=xen-devel-bounces@lists.xen.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id f80si2348185ioj.36.2017.05.10.07.29.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 May 2017 07:29:10 -0700 (PDT) Received-SPF: neutral (google.com: 192.237.175.120 is neither permitted nor denied by best guess record for domain of xen-devel-bounces@lists.xen.org) client-ip=192.237.175.120; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=neutral (google.com: 192.237.175.120 is neither permitted nor denied by best guess record for domain of xen-devel-bounces@lists.xen.org) smtp.mailfrom=xen-devel-bounces@lists.xen.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d8SaC-0002ap-SS; Wed, 10 May 2017 14:27:16 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d8SaB-0002aP-3l for xen-devel@lists.xenproject.org; Wed, 10 May 2017 14:27:15 +0000 Received: from [85.158.139.211] by server-16.bemta-5.messagelabs.com id 4D/C4-01752-24323195; Wed, 10 May 2017 14:27:14 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrAIsWRWlGSWpSXmKPExsXiVRtsrOuoLBx p8PGVmMX3LZOZHBg9Dn+4whLAGMWamZeUX5HAmvH24DWmgj0HGCvOnT/M2MD4vqSLkYtDSGA6 o8TXzWeYQRwWgXnMEis+HWAFcSQE+lklVr1fA+RwAjlpEv0nvjNB2JUSN9u/gcWFBLQkjp6aD WU3MUk8n1XTxcjBwSZgIjGrQwIkLCKgJHFv1WSwVmaBUIl/z9rYQWxhgTiJyx8a2UBsFgFVia tf3zKC2LwC3hKLJ/2FWisncfNcJzOIzSngIzH37CZmiFXeEq1rrzJPYBRYwMiwilGjOLWoLLV I18hEL6koMz2jJDcxM0fX0MBULze1uDgxPTUnMalYLzk/dxMjMLTqGRgYdzDenOx3iFGSg0lJ lFd3l1CkEF9SfkplRmJxRnxRaU5q8SFGGQ4OJQne/4rCkUKCRanpqRVpmTnAIIdJS3DwKInwa igBpXmLCxJzizPTIVKnGHU5Hq388Z5JiCUvPy9VSpzXEaRIAKQoozQPbgQs4i4xykoJ8zIyMD AI8RSkFuVmlqDKv2IU52BUEuZtA7mEJzOvBG7TK6AjmICOCGQQADmiJBEhJdXAGKg5t7Tn970 bN1UYegTjbZnLpDhYC3znlTFbHEjy1nHVb/pefuzhjjPdtbWF9w3bNuvF9kc4JPywNLud1dku w3kna0f3igif145hq/2PM77j+NwQMzUjUUzEWs1389Zgvpu/O49u7r26dMuZHimzrpDSVN3qM rZ3+2ffzDR7+Kf13PyzrZxKLMUZiYZazEXFiQB5pdXgswIAAA== X-Env-Sender: bhupinder.thakur@linaro.org X-Msg-Ref: server-8.tower-206.messagelabs.com!1494426431!97181031!1 X-Originating-IP: [74.125.83.51] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.4.12; banners=-,-,- X-VirusChecked: Checked Received: (qmail 35615 invoked from network); 10 May 2017 14:27:12 -0000 Received: from mail-pg0-f51.google.com (HELO mail-pg0-f51.google.com) (74.125.83.51) by server-8.tower-206.messagelabs.com with AES128-GCM-SHA256 encrypted SMTP; 10 May 2017 14:27:12 -0000 Received: by mail-pg0-f51.google.com with SMTP id o3so17554417pgn.2 for ; Wed, 10 May 2017 07:27:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=8fPxEO2tipVBPIkcCfFz3ZsTN5z4D1LSeoHm1pkTrF4=; b=DQK42EwrD2XFDbGbV4LeqmWwynRhhdMA9Br4AMt8WCoF9bvELWSnHlAyU67dt8pFD0 /PpT4WaCQTv4BZjw1DltXSMgLNA2WNolZYl8nXAh4mfg6q4Gn+LoEtTt52ikPGicwSa5 ibteUI+Tluw7Ot13TORItTkzZyHICYxdzw2og= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=8fPxEO2tipVBPIkcCfFz3ZsTN5z4D1LSeoHm1pkTrF4=; b=QUIn86cEN1MEyaIR0Eqw+yoA0fGF9VepHFsUai/khNwMZfkAzno3RgPUJ+5YHGuzei tx/sdTgBO4j/9tKUULMBd5u3vszN5o9iTDfV3tO8XMe9tr0Mcc1sLnKnnd7y27GkjZYU T4iRfhfOjajGUdQURigvRg0ybDcdtay2T6BjUvkY6o/hp3NP0wdpWLjzHWft4qsJF8kR g0foXOkXPcGXqCTgHTr9TcxPPfQnLXLLXGUASrFD89PryzRv+CWL7s6lT77FqN8MtIzL 7z/+4beXsnvFPr21peia9N3Xo/qBnhwkvpSCq6mIVlff+4VDxG7+nyUcjTMVhniP9trF meyg== X-Gm-Message-State: AODbwcDY8emGqgVU0DgdciNHCUEjwsgw6v6dWZhYR+Cd/giL+W27jywp lVTRi9ypA5Lmdjsr26YocQ== X-Received: by 10.98.156.201 with SMTP id u70mr6266269pfk.76.1494426431044; Wed, 10 May 2017 07:27:11 -0700 (PDT) Received: from blr-ubuntu-linaro.wlan.qualcomm.com ([61.0.91.57]) by smtp.gmail.com with ESMTPSA id k79sm6432320pfj.6.2017.05.10.07.27.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 10 May 2017 07:27:10 -0700 (PDT) From: Bhupinder Thakur To: xen-devel@lists.xenproject.org Date: Wed, 10 May 2017 19:54:52 +0530 Message-Id: <1494426293-32481-2-git-send-email-bhupinder.thakur@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1494426293-32481-1-git-send-email-bhupinder.thakur@linaro.org> References: <1494426293-32481-1-git-send-email-bhupinder.thakur@linaro.org> Cc: Julien Grall , Stefano Stabellini Subject: [Xen-devel] [PATCH 02/12 v3] xen/arm: vpl011: Define generic vreg_reg* access functions in vreg.h X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" This patch redefines the vgic_reg* access functions to vreg_reg* functions. These are generic functions, which will be used by the vgic emulation code to access the vgic registers. PL011 emulation code will also use vreg_reg* access functions. Signed-off-by: Bhupinder Thakur --- xen/arch/arm/vgic-v2.c | 28 +++++------ xen/arch/arm/vgic-v3.c | 40 +++++++-------- xen/include/asm-arm/vgic.h | 12 ----- xen/include/asm-arm/vreg.h | 119 +++++++++++++++++++++++++-------------------- 4 files changed, 99 insertions(+), 100 deletions(-) diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c index dc9f95b..3e35a90 100644 --- a/xen/arch/arm/vgic-v2.c +++ b/xen/arch/arm/vgic-v2.c @@ -179,7 +179,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info, case VREG32(GICD_CTLR): if ( dabt.size != DABT_WORD ) goto bad_width; vgic_lock(v); - *r = vgic_reg32_extract(v->domain->arch.vgic.ctlr, info); + *r = vreg_reg32_extract(v->domain->arch.vgic.ctlr, info); vgic_unlock(v); return 1; @@ -194,7 +194,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info, | DIV_ROUND_UP(v->domain->arch.vgic.nr_spis, 32); vgic_unlock(v); - *r = vgic_reg32_extract(typer, info); + *r = vreg_reg32_extract(typer, info); return 1; } @@ -205,7 +205,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info, * XXX Do we need a JEP106 manufacturer ID? * Just use the physical h/w value for now */ - *r = vgic_reg32_extract(0x0000043b, info); + *r = vreg_reg32_extract(0x0000043b, info); return 1; case VRANGE32(0x00C, 0x01C): @@ -226,7 +226,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info, rank = vgic_rank_offset(v, 1, gicd_reg - GICD_ISENABLER, DABT_WORD); if ( rank == NULL) goto read_as_zero; vgic_lock_rank(v, rank, flags); - *r = vgic_reg32_extract(rank->ienable, info); + *r = vreg_reg32_extract(rank->ienable, info); vgic_unlock_rank(v, rank, flags); return 1; @@ -235,7 +235,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info, rank = vgic_rank_offset(v, 1, gicd_reg - GICD_ICENABLER, DABT_WORD); if ( rank == NULL) goto read_as_zero; vgic_lock_rank(v, rank, flags); - *r = vgic_reg32_extract(rank->ienable, info); + *r = vreg_reg32_extract(rank->ienable, info); vgic_unlock_rank(v, rank, flags); return 1; @@ -262,7 +262,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info, gicd_reg - GICD_IPRIORITYR, DABT_WORD)]; vgic_unlock_rank(v, rank, flags); - *r = vgic_reg32_extract(ipriorityr, info); + *r = vreg_reg32_extract(ipriorityr, info); return 1; } @@ -280,7 +280,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info, vgic_lock_rank(v, rank, flags); itargetsr = vgic_fetch_itargetsr(rank, gicd_reg - GICD_ITARGETSR); vgic_unlock_rank(v, rank, flags); - *r = vgic_reg32_extract(itargetsr, info); + *r = vreg_reg32_extract(itargetsr, info); return 1; } @@ -299,7 +299,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info, icfgr = rank->icfg[REG_RANK_INDEX(2, gicd_reg - GICD_ICFGR, DABT_WORD)]; vgic_unlock_rank(v, rank, flags); - *r = vgic_reg32_extract(icfgr, info); + *r = vreg_reg32_extract(icfgr, info); return 1; } @@ -424,7 +424,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info, if ( dabt.size != DABT_WORD ) goto bad_width; /* Ignore all but the enable bit */ vgic_lock(v); - vgic_reg32_update(&v->domain->arch.vgic.ctlr, r, info); + vreg_reg32_update(&v->domain->arch.vgic.ctlr, r, info); v->domain->arch.vgic.ctlr &= GICD_CTL_ENABLE; vgic_unlock(v); @@ -454,7 +454,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info, if ( rank == NULL) goto write_ignore; vgic_lock_rank(v, rank, flags); tr = rank->ienable; - vgic_reg32_setbits(&rank->ienable, r, info); + vreg_reg32_setbits(&rank->ienable, r, info); vgic_enable_irqs(v, (rank->ienable) & (~tr), rank->index); vgic_unlock_rank(v, rank, flags); return 1; @@ -465,7 +465,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info, if ( rank == NULL) goto write_ignore; vgic_lock_rank(v, rank, flags); tr = rank->ienable; - vgic_reg32_clearbits(&rank->ienable, r, info); + vreg_reg32_clearbits(&rank->ienable, r, info); vgic_disable_irqs(v, (~rank->ienable) & tr, rank->index); vgic_unlock_rank(v, rank, flags); return 1; @@ -508,7 +508,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info, ipriorityr = &rank->ipriorityr[REG_RANK_INDEX(8, gicd_reg - GICD_IPRIORITYR, DABT_WORD)]; - vgic_reg32_update(ipriorityr, r, info); + vreg_reg32_update(ipriorityr, r, info); vgic_unlock_rank(v, rank, flags); return 1; } @@ -529,7 +529,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info, if ( rank == NULL) goto write_ignore; vgic_lock_rank(v, rank, flags); itargetsr = vgic_fetch_itargetsr(rank, gicd_reg - GICD_ITARGETSR); - vgic_reg32_update(&itargetsr, r, info); + vreg_reg32_update(&itargetsr, r, info); vgic_store_itargetsr(v->domain, rank, gicd_reg - GICD_ITARGETSR, itargetsr); vgic_unlock_rank(v, rank, flags); @@ -551,7 +551,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info, rank = vgic_rank_offset(v, 2, gicd_reg - GICD_ICFGR, DABT_WORD); if ( rank == NULL) goto write_ignore; vgic_lock_rank(v, rank, flags); - vgic_reg32_update(&rank->icfg[REG_RANK_INDEX(2, gicd_reg - GICD_ICFGR, + vreg_reg32_update(&rank->icfg[REG_RANK_INDEX(2, gicd_reg - GICD_ICFGR, DABT_WORD)], r, info); vgic_unlock_rank(v, rank, flags); diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c index d10757a..e1213d9 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -181,7 +181,7 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info, case VREG32(GICR_IIDR): if ( dabt.size != DABT_WORD ) goto bad_width; - *r = vgic_reg32_extract(GICV3_GICR_IIDR_VAL, info); + *r = vreg_reg32_extract(GICV3_GICR_IIDR_VAL, info); return 1; case VREG64(GICR_TYPER): @@ -199,7 +199,7 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info, if ( v->arch.vgic.flags & VGIC_V3_RDIST_LAST ) typer |= GICR_TYPER_LAST; - *r = vgic_reg64_extract(typer, info); + *r = vreg_reg64_extract(typer, info); return 1; } @@ -257,7 +257,7 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info, case VREG32(GICR_SYNCR): if ( dabt.size != DABT_WORD ) goto bad_width; /* RO . But when read it always returns busy bito bit[0] */ - *r = vgic_reg32_extract(GICR_SYNCR_NOT_BUSY, info); + *r = vreg_reg32_extract(GICR_SYNCR_NOT_BUSY, info); return 1; case 0x00C8: @@ -284,7 +284,7 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info, case VREG32(GICR_PIDR2): if ( dabt.size != DABT_WORD ) goto bad_width; - *r = vgic_reg32_extract(GICV3_GICR_PIDR2, info); + *r = vreg_reg32_extract(GICV3_GICR_PIDR2, info); return 1; case 0xFFEC ... 0xFFFC: @@ -328,7 +328,7 @@ read_reserved: return 1; read_unknown: - *r = vgic_reg64_extract(0xdeadbeafdeadbeaf, info); + *r = vreg_reg64_extract(0xdeadbeafdeadbeaf, info); return 1; } @@ -489,7 +489,7 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v, rank = vgic_rank_offset(v, 1, reg - GICD_ISENABLER, DABT_WORD); if ( rank == NULL ) goto read_as_zero; vgic_lock_rank(v, rank, flags); - *r = vgic_reg32_extract(rank->ienable, info); + *r = vreg_reg32_extract(rank->ienable, info); vgic_unlock_rank(v, rank, flags); return 1; @@ -498,7 +498,7 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v, rank = vgic_rank_offset(v, 1, reg - GICD_ICENABLER, DABT_WORD); if ( rank == NULL ) goto read_as_zero; vgic_lock_rank(v, rank, flags); - *r = vgic_reg32_extract(rank->ienable, info); + *r = vreg_reg32_extract(rank->ienable, info); vgic_unlock_rank(v, rank, flags); return 1; @@ -525,7 +525,7 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v, DABT_WORD)]; vgic_unlock_rank(v, rank, flags); - *r = vgic_reg32_extract(ipriorityr, info); + *r = vreg_reg32_extract(ipriorityr, info); return 1; } @@ -541,7 +541,7 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v, icfgr = rank->icfg[REG_RANK_INDEX(2, reg - GICD_ICFGR, DABT_WORD)]; vgic_unlock_rank(v, rank, flags); - *r = vgic_reg32_extract(icfgr, info); + *r = vreg_reg32_extract(icfgr, info); return 1; } @@ -585,7 +585,7 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v, if ( rank == NULL ) goto write_ignore; vgic_lock_rank(v, rank, flags); tr = rank->ienable; - vgic_reg32_setbits(&rank->ienable, r, info); + vreg_reg32_setbits(&rank->ienable, r, info); vgic_enable_irqs(v, (rank->ienable) & (~tr), rank->index); vgic_unlock_rank(v, rank, flags); return 1; @@ -596,7 +596,7 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v, if ( rank == NULL ) goto write_ignore; vgic_lock_rank(v, rank, flags); tr = rank->ienable; - vgic_reg32_clearbits(&rank->ienable, r, info); + vreg_reg32_clearbits(&rank->ienable, r, info); vgic_disable_irqs(v, (~rank->ienable) & tr, rank->index); vgic_unlock_rank(v, rank, flags); return 1; @@ -638,7 +638,7 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v, vgic_lock_rank(v, rank, flags); ipriorityr = &rank->ipriorityr[REG_RANK_INDEX(8, reg - GICD_IPRIORITYR, DABT_WORD)]; - vgic_reg32_update(ipriorityr, r, info); + vreg_reg32_update(ipriorityr, r, info); vgic_unlock_rank(v, rank, flags); return 1; } @@ -653,7 +653,7 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v, rank = vgic_rank_offset(v, 2, reg - GICD_ICFGR, DABT_WORD); if ( rank == NULL ) goto write_ignore; vgic_lock_rank(v, rank, flags); - vgic_reg32_update(&rank->icfg[REG_RANK_INDEX(2, reg - GICD_ICFGR, + vreg_reg32_update(&rank->icfg[REG_RANK_INDEX(2, reg - GICD_ICFGR, DABT_WORD)], r, info); vgic_unlock_rank(v, rank, flags); @@ -901,7 +901,7 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info, case VREG32(GICD_CTLR): if ( dabt.size != DABT_WORD ) goto bad_width; vgic_lock(v); - *r = vgic_reg32_extract(v->domain->arch.vgic.ctlr, info); + *r = vreg_reg32_extract(v->domain->arch.vgic.ctlr, info); vgic_unlock(v); return 1; @@ -926,14 +926,14 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info, typer |= (irq_bits - 1) << GICD_TYPE_ID_BITS_SHIFT; - *r = vgic_reg32_extract(typer, info); + *r = vreg_reg32_extract(typer, info); return 1; } case VREG32(GICD_IIDR): if ( dabt.size != DABT_WORD ) goto bad_width; - *r = vgic_reg32_extract(GICV3_GICD_IIDR_VAL, info); + *r = vreg_reg32_extract(GICV3_GICD_IIDR_VAL, info); return 1; case VREG32(0x000C): @@ -1026,7 +1026,7 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info, irouter = vgic_fetch_irouter(rank, gicd_reg - GICD_IROUTER); vgic_unlock_rank(v, rank, flags); - *r = vgic_reg64_extract(irouter, info); + *r = vreg_reg64_extract(irouter, info); return 1; } @@ -1044,7 +1044,7 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info, case VREG32(GICD_PIDR2): /* GICv3 identification value */ if ( dabt.size != DABT_WORD ) goto bad_width; - *r = vgic_reg32_extract(GICV3_GICD_PIDR2, info); + *r = vreg_reg32_extract(GICV3_GICD_PIDR2, info); return 1; case VRANGE32(0xFFEC, 0xFFFC): @@ -1107,7 +1107,7 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info, vgic_lock(v); - vgic_reg32_update(&ctlr, r, info); + vreg_reg32_update(&ctlr, r, info); /* Only EnableGrp1A can be changed */ if ( ctlr & GICD_CTLR_ENABLE_G1A ) @@ -1213,7 +1213,7 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info, if ( rank == NULL ) goto write_ignore; vgic_lock_rank(v, rank, flags); irouter = vgic_fetch_irouter(rank, gicd_reg - GICD_IROUTER); - vgic_reg64_update(&irouter, r, info); + vreg_reg64_update(&irouter, r, info); vgic_store_irouter(v->domain, rank, gicd_reg - GICD_IROUTER, irouter); vgic_unlock_rank(v, rank, flags); return 1; diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h index c838298..75c716e 100644 --- a/xen/include/asm-arm/vgic.h +++ b/xen/include/asm-arm/vgic.h @@ -172,18 +172,6 @@ static inline int REG_RANK_NR(int b, uint32_t n) } } -/* - * 64 bits registers are only supported on platform with 64-bit long. - * This is also allow us to optimize the 32 bit case by using - * unsigned long rather than uint64_t - */ -#if BITS_PER_LONG == 64 -VGIC_REG_HELPERS(64, 0x7); -#endif -VGIC_REG_HELPERS(32, 0x3); - -#undef VGIC_REG_HELPERS - enum gic_sgi_mode; /* diff --git a/xen/include/asm-arm/vreg.h b/xen/include/asm-arm/vreg.h index 1442c58..e127114 100644 --- a/xen/include/asm-arm/vreg.h +++ b/xen/include/asm-arm/vreg.h @@ -107,102 +107,113 @@ static inline bool vreg_emulate_sysreg64(struct cpu_user_regs *regs, union hsr h #endif -#define VGIC_REG_MASK(size) ((~0UL) >> (BITS_PER_LONG - ((1 << (size)) * 8))) +#define VREG_REG_MASK(size) ((~0UL) >> (BITS_PER_LONG - ((1 << (size)) * 8))) /* * The check on the size supported by the register has to be done by - * the caller of vgic_regN_*. + * the caller of vreg_regN_*. * - * vgic_reg_* should never be called directly. Instead use the vgic_regN_* + * vreg_reg_* should never be called directly. Instead use the vreg_regN_* * according to size of the emulated register * * Note that the alignment fault will always be taken in the guest * (see B3.12.7 DDI0406.b). */ -static inline register_t vgic_reg_extract(unsigned long reg, +static inline register_t vreg_reg_extract(unsigned long reg, unsigned int offset, enum dabt_size size) { reg >>= 8 * offset; - reg &= VGIC_REG_MASK(size); + reg &= VREG_REG_MASK(size); return reg; } -static inline void vgic_reg_update(unsigned long *reg, register_t val, +static inline void vreg_reg_update(unsigned long *reg, register_t val, unsigned int offset, enum dabt_size size) { - unsigned long mask = VGIC_REG_MASK(size); + unsigned long mask = VREG_REG_MASK(size); int shift = offset * 8; *reg &= ~(mask << shift); *reg |= ((unsigned long)val & mask) << shift; } -static inline void vgic_reg_setbits(unsigned long *reg, register_t bits, +static inline void vreg_reg_setbits(unsigned long *reg, register_t bits, unsigned int offset, enum dabt_size size) { - unsigned long mask = VGIC_REG_MASK(size); + unsigned long mask = VREG_REG_MASK(size); int shift = offset * 8; *reg |= ((unsigned long)bits & mask) << shift; } -static inline void vgic_reg_clearbits(unsigned long *reg, register_t bits, +static inline void vreg_reg_clearbits(unsigned long *reg, register_t bits, unsigned int offset, enum dabt_size size) { - unsigned long mask = VGIC_REG_MASK(size); + unsigned long mask = VREG_REG_MASK(size); int shift = offset * 8; *reg &= ~(((unsigned long)bits & mask) << shift); } -/* N-bit register helpers */ -#define VGIC_REG_HELPERS(sz, offmask) \ -static inline register_t vgic_reg##sz##_extract(uint##sz##_t reg, \ - const mmio_info_t *info)\ -{ \ - return vgic_reg_extract(reg, info->gpa & offmask, \ - info->dabt.size); \ -} \ - \ -static inline void vgic_reg##sz##_update(uint##sz##_t *reg, \ - register_t val, \ - const mmio_info_t *info) \ -{ \ - unsigned long tmp = *reg; \ - \ - vgic_reg_update(&tmp, val, info->gpa & offmask, \ - info->dabt.size); \ - \ - *reg = tmp; \ -} \ - \ -static inline void vgic_reg##sz##_setbits(uint##sz##_t *reg, \ - register_t bits, \ - const mmio_info_t *info) \ -{ \ - unsigned long tmp = *reg; \ - \ - vgic_reg_setbits(&tmp, bits, info->gpa & offmask, \ - info->dabt.size); \ - \ - *reg = tmp; \ -} \ - \ -static inline void vgic_reg##sz##_clearbits(uint##sz##_t *reg, \ - register_t bits, \ - const mmio_info_t *info) \ -{ \ - unsigned long tmp = *reg; \ - \ - vgic_reg_clearbits(&tmp, bits, info->gpa & offmask, \ - info->dabt.size); \ - \ - *reg = tmp; \ +#define DEFINE_VREG_REG_HELPERS(sz, offmask) \ +/* N-bit register helpers */ \ +static inline register_t vreg_reg##sz##_extract(uint##sz##_t reg, \ + const mmio_info_t *info) \ +{ \ + return vreg_reg_extract(reg, info->gpa & offmask, \ + info->dabt.size); \ +} \ + \ +static inline void vreg_reg##sz##_update(uint##sz##_t *reg, \ + register_t val, \ + const mmio_info_t *info) \ +{ \ + unsigned long tmp = *reg; \ + \ + vreg_reg_update(&tmp, val, info->gpa & offmask, \ + info->dabt.size); \ + \ + *reg = tmp; \ +} \ + \ +static inline void vreg_reg##sz##_setbits(uint##sz##_t *reg, \ + register_t bits, \ + const mmio_info_t *info) \ +{ \ + unsigned long tmp = *reg; \ + \ + vreg_reg_setbits(&tmp, bits, info->gpa & offmask, \ + info->dabt.size); \ + \ + *reg = tmp; \ +} \ + \ +static inline void vreg_reg##sz##_clearbits(uint##sz##_t *reg, \ + register_t bits, \ + const mmio_info_t *info) \ +{ \ + unsigned long tmp = *reg; \ + \ + vreg_reg_clearbits(&tmp, bits, info->gpa & offmask, \ + info->dabt.size); \ + \ + *reg = tmp; \ } +/* + * 64 bits registers are only supported on platform with 64-bit long. + * This is also allow us to optimize the 32 bit case by using + * unsigned long rather than uint64_t + */ +#if BITS_PER_LONG == 64 +DEFINE_VREG_REG_HELPERS(64, 0x7); +#endif +DEFINE_VREG_REG_HELPERS(32, 0x3); + +#undef DEFINE_VREG_REG_HELPERS #endif /* __ASM_ARM_VREG__ */ From patchwork Wed May 10 14:24:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhupinder Thakur X-Patchwork-Id: 98997 Delivered-To: patch@linaro.org Received: by 10.140.96.100 with SMTP id j91csp253248qge; Wed, 10 May 2017 07:29:20 -0700 (PDT) X-Received: by 10.36.74.82 with SMTP id k79mr1558561itb.58.1494426560918; Wed, 10 May 2017 07:29:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1494426560; cv=none; d=google.com; s=arc-20160816; b=NZbPZtvTMYip00brXosRIAiXMbz4B3FApp82U/Por0EbxSFcUMLFO8Gz35Ts9JSQdp jp3oUQfkKlO4Gi8fs085yd2ux/NxdN+McefsdP0WLhzbsXWq7/oUZMj1G7Ggx9S6+tjy aQJv03fTbinlePKrH1Wlw4prE3+ns41OakVGOkx3cWXtocZd3wdBgeek/tx+eF+yvvR/ HN34hwjcVRWia6596Ljq8ynBTflh61NeaLC+fS6r5wqQccz7vBSdVgEPLams07veSIrJ sxHkPX7GlDXpD4KtzlIFE2oxAGHJi7tA5HllQJ8iN74f6c4mM2KaF8AxAnB3zj2AYcUl 1QeQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:cc:references:in-reply-to:message-id:date:to :from:dkim-signature:arc-authentication-results; bh=MbP0XaOTAiCB/tirJTkYaIhpD2zIh2QV6O3oBgEqCp4=; b=HCyebNtSTHu9hixDLnC8jaPaJQH8G8/eUjJGzeuTduW2/f7QawuzQ0Hw0DAafpHQsd d6b/l85S2RyuoyXdmOqxPaBdWAthsMtfVxY+OsDLhngtD+boRy0EUNvmP8OV7cwKbvPv O2+4vqpcLdc41X8KzSPVHEZooFZXg02kacmE6Ebe2XE1Bc7aYqvmnFpq7HBn8aGQfUF3 ZQuqDKMPk+2kRMYU7p+IGLax1DN98C3P8fwS3rxOt0JJrVxxf6DLeeORROKsvnrY9h/q pivJTXenY70xtycG8pSNzJnkg8fNl+evwrAKodpoQdTnETeEZrpa4wYRV2VRcQfylLoo QhDA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=neutral (google.com: 192.237.175.120 is neither permitted nor denied by best guess record for domain of xen-devel-bounces@lists.xen.org) smtp.mailfrom=xen-devel-bounces@lists.xen.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id e129si3361758ite.12.2017.05.10.07.29.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 May 2017 07:29:20 -0700 (PDT) Received-SPF: neutral (google.com: 192.237.175.120 is neither permitted nor denied by best guess record for domain of xen-devel-bounces@lists.xen.org) client-ip=192.237.175.120; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=neutral (google.com: 192.237.175.120 is neither permitted nor denied by best guess record for domain of xen-devel-bounces@lists.xen.org) smtp.mailfrom=xen-devel-bounces@lists.xen.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d8SaK-0002da-6y; Wed, 10 May 2017 14:27:24 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d8SaI-0002cx-6C for xen-devel@lists.xenproject.org; Wed, 10 May 2017 14:27:22 +0000 Received: from [85.158.139.211] by server-1.bemta-5.messagelabs.com id 55/B4-01992-94323195; Wed, 10 May 2017 14:27:21 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrCIsWRWlGSWpSXmKPExsXiVRuso+uhLBx pcGaqosX3LZOZHBg9Dn+4whLAGMWamZeUX5HAmvHpXFLB0nbGiq9rN7E0MP5O72Lk4hASmMko seDqbSYQh0VgHrPE6UXvmUEcCYF+VolVra2sXYwcQE6cxIybjBBmpcSf1UVdjJxAzVoSR0/NZ oUY1MQkcX75fBaQGjYBE4lZHRIgNSICShL3Vk1mArGZBUIl/j1rYwexhQW8JGYef84MYrMIqE osaHsGZvMKeEvsvvGKBcSWEJCTuHmuEyzOKeAjMffsJmaIvd4SrWuvMk9gFFjAyLCKUaM4tag stUjXyFgvqSgzPaMkNzEzR9fQwFQvN7W4ODE9NScxqVgvOT93EyMwrOoZGBh3MO5o9zvEKMnB pCTKq7tLKFKILyk/pTIjsTgjvqg0J7X4EKMMB4eSBO9/ReFIIcGi1PTUirTMHGCAw6QlOHiUR Hhfg6R5iwsSc4sz0yFSpxiNOa60fnzPxPFo5Y/3TEIsefl5qVLivJdBSgVASjNK8+AGwSLvEq OslDAvIwMDgxBPQWpRbmYJqvwrRnEORiVh3kMgU3gy80rg9r0COoUJ6JRABgGQU0oSEVJSDYz B1t2XOU5aslXyvCrepxenO30Z96Mrpjbf5NY2XLYp9/y5Zc6iVdOecBX8+PPdM+a3gcuOiYc1 31vpBzE/eJb3Z+3piRM/Tlt0WM/P8KLisn8u9W6mAjZ+PxjT3ednCln+WF2tvMfFtiXo2s16z 5yCLEmpbVI3stJK//AtWSctVx53S7KyT1iJpTgj0VCLuag4EQDCptuYtwIAAA== X-Env-Sender: bhupinder.thakur@linaro.org X-Msg-Ref: server-2.tower-206.messagelabs.com!1494426438!76704588!1 X-Originating-IP: [74.125.83.44] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 9.4.12; banners=-,-,- X-VirusChecked: Checked Received: (qmail 48705 invoked from network); 10 May 2017 14:27:19 -0000 Received: from mail-pg0-f44.google.com (HELO mail-pg0-f44.google.com) (74.125.83.44) by server-2.tower-206.messagelabs.com with AES128-GCM-SHA256 encrypted SMTP; 10 May 2017 14:27:19 -0000 Received: by mail-pg0-f44.google.com with SMTP id u187so17524123pgb.0 for ; Wed, 10 May 2017 07:27:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=1IO6DEQu96gAePQhYkdc0S1f2dANsW4ynSxGOtqdkE0=; b=jGodQhhJI+Mf00nAN+aL7XWUh1o2Ou71uVywM3pZwO+igN0ZLfI5J0QFni2KPVg/NO wPGN3XBf4aELAmJ+OyY+Y912hh+ktLNfnQXm7gap/ggbmDsJmxLNwg57glLHP/lbsEud kT7Q7Cqb1mp3QyYnGeW/zUdn7DoVeUEvec52Q= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=1IO6DEQu96gAePQhYkdc0S1f2dANsW4ynSxGOtqdkE0=; b=H3zMPYl/8neh9fFUlmeNLWgtCVB4LvQyo7lYIFJ7e0Z9V57i7hJTUfEJEAurMwtC8g tpt6JM8EtqM8RVLrJY/sRx9y/t6EU4m/CQsUL+wKvCV00ArqT4Vvo6qcLTXE8d5O+U+u U5kWQh7d7ww4R9N0zkurCoCfM4JPhxZOsi8TznKAf93/JdOzYbK1w7qoxZRQsboVmqa1 a6dB8Jtm7PGoBkJBqpaJ2wo9/2nH6DW1szVVsZJdmuBsBCEP+XOrquNVbvlmYaim0VmB aIwaCmMXp+nDxatrwysEH1vangtEIJMilBXhdrDzOOKX2/MDiN2Z5uY+pA1xyRvvRfnJ mJTA== X-Gm-Message-State: AODbwcCJwQqk6N6uhWdi4mM36vWqxK7hSOS6yKiSLi09HytXuOrRbICj JnkHF/UNQ+ZFkQVV X-Received: by 10.84.138.193 with SMTP id 59mr8666743plp.184.1494426437314; Wed, 10 May 2017 07:27:17 -0700 (PDT) Received: from blr-ubuntu-linaro.wlan.qualcomm.com ([61.0.91.57]) by smtp.gmail.com with ESMTPSA id k79sm6432320pfj.6.2017.05.10.07.27.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 10 May 2017 07:27:16 -0700 (PDT) From: Bhupinder Thakur To: xen-devel@lists.xenproject.org Date: Wed, 10 May 2017 19:54:53 +0530 Message-Id: <1494426293-32481-3-git-send-email-bhupinder.thakur@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1494426293-32481-1-git-send-email-bhupinder.thakur@linaro.org> References: <1494426293-32481-1-git-send-email-bhupinder.thakur@linaro.org> Cc: Julien Grall , Stefano Stabellini Subject: [Xen-devel] [PATCH 03/12 v3] xen/arm: vpl011: Add pl011 uart emulation in Xen X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" Add emulation code to emulate read/write access to pl011 registers and pl011 interrupts: - Emulate DR read/write by reading and writing from/to the IN and OUT ring buffers and raising an event to the backend when there is data in the OUT ring buffer and injecting an interrupt to the guest when there is data in the IN ring buffer - Other registers are related to interrupt management and essentially control when interrupts are delivered to the guest The SBSA compliant pl011 uart is covered in Appendix B of https://static.docs.arm.com/den0029/a/Server_Base_System_Architecture_v3_1_ARM_DEN_0029A.pdf Signed-off-by: Bhupinder Thakur --- Changes since v2: - Use generic vreg_reg* for read/write of registers emulating pl011. - Use generic ring buffer functions defined using DEFINE_XEN_FLEX_RING. - Renamed the SPI injection function to vpl011_update_spi() to reflect level triggered nature of pl011 interrupts. - The pl011 register access address should always be the base address of the corresponding register as per section B of the SBSA document. For this reason, the register range address access is not allowed. Changes since v1: - Removed the optimiztion related to sendiing events to xenconsole - Use local variables as ring buffer indices while using the ring buffer xen/arch/arm/Kconfig | 5 + xen/arch/arm/Makefile | 1 + xen/arch/arm/vpl011.c | 350 +++++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/domain.h | 6 + xen/include/asm-arm/pl011-uart.h | 2 + xen/include/asm-arm/vpl011.h | 94 +++++++++++ xen/include/public/arch-arm.h | 8 + 7 files changed, 466 insertions(+) create mode 100644 xen/arch/arm/vpl011.c create mode 100644 xen/include/asm-arm/vpl011.h diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig index d46b98c..c1a0e7f 100644 --- a/xen/arch/arm/Kconfig +++ b/xen/arch/arm/Kconfig @@ -50,6 +50,11 @@ config HAS_ITS prompt "GICv3 ITS MSI controller support" if EXPERT = "y" depends on HAS_GICV3 +config VPL011_CONSOLE + bool "Emulated pl011 console support" + default y + ---help--- + Allows a guest to use pl011 UART as a console endmenu menu "ARM errata workaround via the alternative framework" diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index 49e1fb2..15efc13 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -52,6 +52,7 @@ obj-y += vm_event.o obj-y += vtimer.o obj-y += vpsci.o obj-y += vuart.o +obj-$(CONFIG_VPL011_CONSOLE) += vpl011.o #obj-bin-y += ....o diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c new file mode 100644 index 0000000..2f71148 --- /dev/null +++ b/xen/arch/arm/vpl011.c @@ -0,0 +1,350 @@ +/* + * arch/arm/vpl011.c + * + * Virtual PL011 UART + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static bool vpl011_reg32_check_access(int size) +{ + return (size == DABT_DOUBLE_WORD)? false : true; +} + +static void vpl011_update_spi(struct domain *d) +{ + struct vpl011_s *vpl011 = &d->arch.vpl011; + + if ( vpl011->uartris & vpl011->uartimsc ) + vgic_vcpu_inject_spi(d, GUEST_VPL011_SPI); +} + +static void vpl011_read_data(struct domain *d, uint8_t *data) +{ + unsigned long flags; + struct vpl011_s *vpl011 = &d->arch.vpl011; + struct xencons_interface *intf = vpl011->ring_buf; + + /* + * Initialize the data so that even if there is no data in ring buffer + * 0 is returned. + */ + *data = 0; + + VPL011_LOCK(d, flags); + + /* + * It is expected that there will be data in the ring buffer when this + * function is called since the guest is expected to read the data register + * only if the TXFE flag is not set. + * If the guest still does read when TXFE bit is set then 0 will be returned. + */ + if ( !VPL011_IN_RING_EMPTY(intf) ) + { + XENCONS_RING_IDX in_cons = intf->in_cons; + *data = intf->in[VPL011_RING_IDX_MASK(in_cons, intf->in)]; + smp_mb(); + intf->in_cons = in_cons + 1; + } + + if ( VPL011_IN_RING_EMPTY(intf) ) + { + vpl011->uartfr |= RXFE; + vpl011->uartris &= ~RXI; + } + vpl011->uartfr &= ~RXFF; + VPL011_UNLOCK(d, flags); + + notify_via_xen_event_channel(d, vpl011->evtchn); +} + +static void vpl011_write_data(struct domain *d, uint8_t data) +{ + unsigned long flags; + struct vpl011_s *vpl011 = &d->arch.vpl011; + struct xencons_interface *intf = vpl011->ring_buf; + + VPL011_LOCK(d, flags); + + /* + * It is expected that the ring is not full when this function is called + * as the guest is expected to write to the data register only when the + * TXFF flag is not set. + * In case the guest does write even when the TXFF flag is set then the + * data will be silently dropped. + */ + if ( !VPL011_OUT_RING_FULL(intf) ) + { + XENCONS_RING_IDX out_prod = intf->out_prod; + intf->out[VPL011_RING_IDX_MASK(out_prod, intf->out)] = data; + smp_wmb(); + intf->out_prod = out_prod + 1; + } + + if ( VPL011_OUT_RING_FULL(intf) ) + { + vpl011->uartfr |= TXFF; + vpl011->uartris &= ~TXI; + } + + vpl011->uartfr |= BUSY; + + vpl011->uartfr &= ~TXFE; + + VPL011_UNLOCK(d, flags); + + notify_via_xen_event_channel(d, vpl011->evtchn); +} + +static int vpl011_mmio_read(struct vcpu *v, mmio_info_t *info, register_t *r, void *priv) +{ + uint8_t ch; + struct hsr_dabt dabt = info->dabt; + int vpl011_reg = (int)(info->gpa - GUEST_PL011_BASE); + struct vpl011_s *vpl011 = &v->domain->arch.vpl011; + + if ( !vpl011_reg32_check_access(dabt.size) ) goto bad_width; + + switch ( vpl011_reg ) + { + case DR: + vpl011_read_data(v->domain, &ch); + *r = ch; + break; + + case RSR: + /* It always returns 0 as there are no physical errors. */ + *r = 0; + break; + + case FR: + *r = vreg_reg32_extract(vpl011->uartfr, info); + break; + + case RIS: + *r = vreg_reg32_extract(vpl011->uartris, info); + break; + + case MIS: + *r = vreg_reg32_extract(vpl011->uartris + & vpl011->uartimsc, info); + break; + + case IMSC: + *r = vreg_reg32_extract(vpl011->uartimsc, info); + break; + + case ICR: + /* Only write is valid. */ + return 0; + + default: + gprintk(XENLOG_ERR, "vpl011: unhandled read r%d offset %#08x\n", + dabt.reg, vpl011_reg); + return 0; + } + + return 1; + +bad_width: + gprintk(XENLOG_ERR, "vpl011: bad read width %d r%d offset %#08x\n", + dabt.size, dabt.reg, vpl011_reg); + domain_crash_synchronous(); + return 0; + +} + +static int vpl011_mmio_write(struct vcpu *v, mmio_info_t *info, register_t r, void *priv) +{ + uint8_t ch = ((struct uartdr_reg *)&r)->data; + struct hsr_dabt dabt = info->dabt; + int vpl011_reg = (int)(info->gpa - GUEST_PL011_BASE); + struct vpl011_s *vpl011 = &v->domain->arch.vpl011; + + if ( !vpl011_reg32_check_access(dabt.size) ) goto bad_width; + + switch ( vpl011_reg ) + { + case DR: + vpl011_write_data(v->domain, ch); + break; + + case RSR: /* Nothing to clear. */ + break; + + case FR: + case RIS: + case MIS: + goto write_ignore; + + case IMSC: + vreg_reg32_update(&vpl011->uartimsc, r, info); + vpl011_update_spi(v->domain); + break; + + case ICR: + vreg_reg32_clearbits(&vpl011->uartris, r, info); + vpl011_update_spi(v->domain); + break; + + default: + gprintk(XENLOG_ERR, "vpl011: unhandled write r%d offset %#08x\n", + dabt.reg, vpl011_reg); + return 0; + } + +write_ignore: + return 1; + +bad_width: + gprintk(XENLOG_ERR, "vpl011: bad write width %d r%d offset %#08x\n", + dabt.size, dabt.reg, vpl011_reg); + domain_crash_synchronous(); + return 0; + +} + +static const struct mmio_handler_ops vpl011_mmio_handler = { + .read = vpl011_mmio_read, + .write = vpl011_mmio_write, +}; + +int vpl011_map_guest_page(struct domain *d, xen_pfn_t gfn) +{ + struct vpl011_s *vpl011 = &d->arch.vpl011; + + /* Map the guest PFN to Xen address space. */ + return prepare_ring_for_helper(d, + gfn, + &vpl011->ring_page, + &vpl011->ring_buf); +} + +static void vpl011_data_avail(struct domain *d) +{ + unsigned long flags; + struct vpl011_s *vpl011 = &d->arch.vpl011; + struct xencons_interface *intf = vpl011->ring_buf; + RING_IDX in_ring_depth, out_ring_depth; + + VPL011_LOCK(d, flags); + + in_ring_depth = vpl011_queued(intf->in_prod, intf->in_cons, sizeof(intf->in)); + out_ring_depth = vpl011_queued(intf->out_prod, intf->out_cons, sizeof(intf->out)); + + /* Update the uart rx state if the buffer is not empty. */ + if ( in_ring_depth != 0 ) + { + vpl011->uartfr &= ~RXFE; + if ( in_ring_depth == VPL011_RING_MAX_DEPTH(intf, in) ) + vpl011->uartfr |= RXFF; + vpl011->uartris |= RXI; + } + + /* Update the uart tx state if the buffer is not full. */ + if ( out_ring_depth != VPL011_RING_MAX_DEPTH(intf, out) ) + { + vpl011->uartfr &= ~TXFF; + vpl011->uartris |= TXI; + if ( out_ring_depth == 0 ) + { + vpl011->uartfr &= ~BUSY; + vpl011->uartfr |= TXFE; + } + } + + VPL011_UNLOCK(d, flags); + + vpl011_update_spi(d); +} + + +static void vpl011_notification(struct vcpu *v, unsigned int port) +{ + vpl011_data_avail(v->domain); +} + +int domain_vpl011_init(struct domain *d, + uint32_t console_domid, + xen_pfn_t gfn, + evtchn_port_t *evtchn) +{ + int rc; + struct vpl011_s *vpl011 = &d->arch.vpl011; + + rc = vpl011_map_guest_page(d, gfn); + if ( rc < 0 ) + goto out; + + rc = vgic_reserve_virq(d, GUEST_VPL011_SPI); + if ( !rc ) + { + rc = -EINVAL; + goto out1; + } + + register_mmio_handler(d, &vpl011_mmio_handler, + GUEST_PL011_BASE, GUEST_PL011_SIZE, NULL); + + spin_lock_init(&vpl011->lock); + + rc = alloc_unbound_xen_event_channel(d, 0, console_domid, + vpl011_notification); + if (rc < 0) + goto out2; + + vpl011->evtchn = *evtchn = rc; + + vpl011->initialized = true; + + return 0; + +out2: + xfree(d->arch.vmmio.handlers); +out1: + destroy_ring_for_helper(&vpl011->ring_buf, vpl011->ring_page); +out: + return rc; +} + +void domain_vpl011_deinit(struct domain *d) +{ + struct vpl011_s *vpl011 = &d->arch.vpl011; + + if ( vpl011->initialized ) + { + free_xen_event_channel(d, vpl011->evtchn); + destroy_ring_for_helper(&vpl011->ring_buf, vpl011->ring_page); + } + vpl011->initialized = false; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h index 6de8082..54611e0 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -11,6 +11,7 @@ #include #include #include +#include struct hvm_domain { @@ -133,6 +134,11 @@ struct arch_domain struct { uint8_t privileged_call_enabled : 1; } monitor; + +#ifdef CONFIG_VPL011_CONSOLE + struct vpl011_s vpl011; +#endif + } __cacheline_aligned; struct arch_vcpu diff --git a/xen/include/asm-arm/pl011-uart.h b/xen/include/asm-arm/pl011-uart.h index 123f477..57e9ec7 100644 --- a/xen/include/asm-arm/pl011-uart.h +++ b/xen/include/asm-arm/pl011-uart.h @@ -49,6 +49,8 @@ /* FR bits */ #define TXFE (1<<7) /* TX FIFO empty */ #define RXFE (1<<4) /* RX FIFO empty */ +#define TXFF (1<<5) /* TX FIFO full */ +#define RXFF (1<<6) /* RX FIFO full */ #define BUSY (1<<3) /* Transmit is not complete */ /* LCR_H bits */ diff --git a/xen/include/asm-arm/vpl011.h b/xen/include/asm-arm/vpl011.h new file mode 100644 index 0000000..df7e6b7 --- /dev/null +++ b/xen/include/asm-arm/vpl011.h @@ -0,0 +1,94 @@ +/* + * include/xen/vpl011.h + * + * Virtual PL011 UART + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 . + */ + +#ifndef _VPL011_H_ + +#define _VPL011_H_ + +#include +#include + +DEFINE_XEN_FLEX_RING(vpl011); + +/* helper macros */ +#define VPL011_RING_IDX_MASK(idx, ring) (vpl011_mask(idx, sizeof(ring))) + +#define VPL011_RING_DEPTH(intf,dir) (vpl011_queued((intf)->dir ## _prod, \ + (intf)->dir ## _cons, \ + sizeof((intf)->dir))) + +#define VPL011_RING_MAX_DEPTH(intf,dir) (sizeof((intf)->dir)) + +#define VPL011_IN_RING_EMPTY(intf) (VPL011_RING_DEPTH(intf, in) == 0) + +#define VPL011_OUT_RING_EMPTY(intf) (VPL011_RING_DEPTH(intf, out) == 0) + +#define VPL011_IN_RING_FULL(intf) (VPL011_RING_DEPTH(intf, in) == VPL011_RING_MAX_DEPTH(intf, in)) + +#define VPL011_OUT_RING_FULL(intf) (VPL011_RING_DEPTH(intf, out) == VPL011_RING_MAX_DEPTH(intf,out)) + +#define VPL011_LOCK(d,flags) spin_lock_irqsave(&(d)->arch.vpl011.lock, flags) +#define VPL011_UNLOCK(d,flags) spin_unlock_irqrestore(&(d)->arch.vpl011.lock, flags) + +struct uartdr_reg { + uint8_t data; + uint8_t error_status:4; + uint8_t reserved1:4; + uint16_t reserved2; + uint32_t reserved3; +}; + +struct vpl011_s { + void *ring_buf; + struct page_info *ring_page; + uint32_t uartfr; /* Flag register */ + uint32_t uartcr; /* Control register */ + uint32_t uartimsc; /* Interrupt mask register*/ + uint32_t uarticr; /* Interrupt clear register */ + uint32_t uartris; /* Raw interrupt status register */ + uint32_t uartmis; /* Masked interrupt register */ + spinlock_t lock; + evtchn_port_t evtchn; + bool initialized; /* Flag which tells whether vpl011 is initialized */ +}; + +#ifdef CONFIG_VPL011_CONSOLE +int domain_vpl011_init(struct domain *d, + uint32_t console_domid, + xen_pfn_t gfn, + evtchn_port_t *evtchn); +void domain_vpl011_deinit(struct domain *d); +#else +int domain_vpl011_init(struct domain *d, + uint32_t console_domid, + xen_pfn_t gfn, + evtchn_port_t *evtchn) { return -ENOSYS; } + +static inline void domain_vpl011_deinit(struct domain *d) { } +#endif + +#endif + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h index bd974fb..5f91207 100644 --- a/xen/include/public/arch-arm.h +++ b/xen/include/public/arch-arm.h @@ -322,6 +322,8 @@ struct xen_arch_domainconfig { * */ uint32_t clock_frequency; + + uint32_t console_domid; }; #endif /* __XEN__ || __XEN_TOOLS__ */ @@ -410,6 +412,10 @@ typedef uint64_t xen_callback_t; #define GUEST_ACPI_BASE 0x20000000ULL #define GUEST_ACPI_SIZE 0x02000000ULL +/* PL011 mappings */ +#define GUEST_PL011_BASE 0x22000000ULL +#define GUEST_PL011_SIZE 0x00001000ULL + /* * 16MB == 4096 pages reserved for guest to use as a region to map its * grant table in. @@ -444,6 +450,8 @@ typedef uint64_t xen_callback_t; #define GUEST_TIMER_PHYS_NS_PPI 30 #define GUEST_EVTCHN_PPI 31 +#define GUEST_VPL011_SPI 32 + /* PSCI functions */ #define PSCI_cpu_suspend 0 #define PSCI_cpu_off 1