From patchwork Fri Jul 20 15:39:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 10537865 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D47D2603B5 for ; Fri, 20 Jul 2018 15:40:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BA0582959F for ; Fri, 20 Jul 2018 15:40:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AE072295C7; Fri, 20 Jul 2018 15:40:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 09AC2295B5 for ; Fri, 20 Jul 2018 15:40:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733101AbeGTQ2s (ORCPT ); Fri, 20 Jul 2018 12:28:48 -0400 Received: from foss.arm.com ([217.140.101.70]:38732 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731892AbeGTQ2s (ORCPT ); Fri, 20 Jul 2018 12:28:48 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id AE73980D; Fri, 20 Jul 2018 08:39:57 -0700 (PDT) Received: from e104803-lin.cambridge.arm.com (e104803-lin.cambridge.arm.com [10.1.206.130]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 130CE3F5B3; Fri, 20 Jul 2018 08:39:55 -0700 (PDT) From: Andre Przywara To: Andrew Jones Cc: Eric Auger , Marc Zyngier , Christoffer Dall , kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, Peter Maydell , qemu-devel@nongnu.org Subject: [kvm-unit-tests PATCH v2 3/4] arm/arm64: GICv2: add GICD_IPRIORITYR testing Date: Fri, 20 Jul 2018 16:39:41 +0100 Message-Id: <20180720153942.26821-4-andre.przywara@arm.com> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180720153942.26821-1-andre.przywara@arm.com> References: <20180720153942.26821-1-andre.przywara@arm.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Some tests for the IPRIORITY registers. The significant number of bits is IMPLEMENTATION DEFINED, but should be the same for every IRQ. Also these registers must be byte-accessible. Check that accesses beyond the implemented IRQ limit are actually read-as-zero/write-ignore. Signed-off-by: Andre Przywara Reviewed-by: Andrew Jones --- arm/gic.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/arm/gic.c b/arm/gic.c index 23cb9a4..57a2995 100644 --- a/arm/gic.c +++ b/arm/gic.c @@ -354,6 +354,83 @@ static void test_typer_v2(uint32_t reg) nr_gic_cpus); } +#define BYTE(reg32, byte) (((reg32) >> ((byte) * 8)) & 0xff) +#define REPLACE_BYTE(reg32, byte, new) (((reg32) & ~(0xff << ((byte) * 8))) |\ + ((new) << ((byte) * 8))) + +/* + * Some registers are byte accessible, do a byte-wide read and write of known + * content to check for this. + * Apply a @mask to cater for special register properties. + * @pattern contains the value already in the register. + */ +static void test_byte_access(void *base_addr, u32 pattern, u32 mask) +{ + u32 reg = readb(base_addr + 1); + + report("byte reads successful (0x%08x => 0x%02x)", + reg == (BYTE(pattern, 1) & (mask >> 8)), + pattern & mask, reg); + + pattern = REPLACE_BYTE(pattern, 2, 0x1f); + writeb(BYTE(pattern, 2), base_addr + 2); + reg = readl(base_addr); + report("byte writes successful (0x%02x => 0x%08x)", + reg == (pattern & mask), BYTE(pattern, 2), reg); +} + +static void test_priorities(int nr_irqs, void *priptr) +{ + u32 orig_prio, reg, pri_bits; + u32 pri_mask, pattern; + void *first_spi = priptr + GIC_FIRST_SPI; + + orig_prio = readl(first_spi); + report_prefix_push("IPRIORITYR"); + + /* + * Determine implemented number of priority bits by writing all 1's + * and checking the number of cleared bits in the value read back. + */ + writel(0xffffffff, first_spi); + pri_mask = readl(first_spi); + + reg = ~pri_mask; + report("consistent priority masking (0x%08x)", + (((reg >> 16) == (reg & 0xffff)) && + ((reg & 0xff) == ((reg >> 8) & 0xff))), pri_mask); + + reg = reg & 0xff; + for (pri_bits = 8; reg & 1; reg >>= 1, pri_bits--) + ; + report("implements at least 4 priority bits (%d)", + pri_bits >= 4, pri_bits); + + pattern = 0; + writel(pattern, first_spi); + report("clearing priorities", readl(first_spi) == pattern); + + /* setting all priorities to their max valus was tested above */ + + report("accesses beyond limit RAZ/WI", + test_readonly_32(priptr + nr_irqs, true)); + + writel(pattern, priptr + nr_irqs - 4); + report("accessing last SPIs", + readl(priptr + nr_irqs - 4) == (pattern & pri_mask)); + + pattern = 0xff7fbf3f; + writel(pattern, first_spi); + report("priorities are preserved", + readl(first_spi) == (pattern & pri_mask)); + + /* The PRIORITY registers are byte accessible. */ + test_byte_access(first_spi, pattern, pri_mask); + + report_prefix_pop(); + writel(orig_prio, first_spi); +} + static void gic_test_mmio(void) { u32 reg; @@ -388,6 +465,8 @@ static void gic_test_mmio(void) report("ICPIDR2 is read-only (0x%08x)", test_readonly_32(idreg, false), reg); + + test_priorities(nr_irqs, gic_dist_base + GICD_IPRIORITYR); } int main(int argc, char **argv)