From patchwork Fri Nov 30 09:47:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jose Abreu X-Patchwork-Id: 1005850 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-snps-arc-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=synopsys.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="rnwq2bMW"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=synopsys.com header.i=@synopsys.com header.b="F+2n0I19"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 435qM35Jm8z9s8F for ; Fri, 30 Nov 2018 20:47:59 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=PMuOYUtYffrgqBqXRuSL6ybcRS5Zyvy6M0mbw/oQfkc=; b=rnw q2bMW3OhTVpHhMwOPn8RR5LkhnZDov/poQWefbfbRsNaD8FD3lL5ahNeZkuwS1C6DkbOX+7MJlQTg UXbfe/7rh5e/jOcDAFhtl1nEyUKMNotN9pbys4BjI66y/Jwfh1fIjdB+itiUAM4fGE3r47CEoddSh AqG2aIaDUfWe0cF2Gtj0lktTbYRkoGuxr3bXJxvib7Qv3jwQyAEcJsEgj4RKxwOZSRwPMQXU3/WIF qrzpwhv5TRoth//WEUz8TSk8naqz91hp4aVw7uuKfgMc3thvDyhDaeVVHryAWOzhksGR9UX3ouaaH fUHsnnUwFlwPoH174bXN9Vj/Rqk2j7w==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gSfOv-0004VJ-Qi; Fri, 30 Nov 2018 09:47:57 +0000 Received: from us01smtprelay-2.synopsys.com ([198.182.47.9] helo=smtprelay.synopsys.com) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gSfOs-0004UR-Ps for linux-snps-arc@lists.infradead.org; Fri, 30 Nov 2018 09:47:56 +0000 Received: from mailhost.synopsys.com (mailhost1.synopsys.com [10.12.238.239]) by smtprelay.synopsys.com (Postfix) with ESMTP id ED84124E204D; Fri, 30 Nov 2018 01:47:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1543571263; bh=AQQ/BgUgp5GV5MOoT50HibXrL1H3upummjpjFm9Swx4=; h=From:To:Cc:Subject:Date:From; b=F+2n0I19lkhCBlZ3HYF1wnrP7E+OBLMZqU6VjN3L33sCtxd+Wo7CTchtBXt2f6BTo tY3LctAcEWYBa7XLJDSmnwPmr6VQH2eiewUIvmTr0a51ESxY7ZD8ojrPJOKpdyLQur A/cyi3i35KsnV5C2CT+kIkuprJ76l9eoYtPx7QIIyXLi58Is3JRdzXcKkezOuyElsJ XQYEgVXMqKVYfYX2246GG288bCVNDzLIpdJ7g+EeXXkBQ0itveR6AFNdC4Zp9qZUYl MQJvmNh6df3OqYMpYJIQM11pUd6LTxfYJoRsuvtChVYZ7a0391Pgm7TjRvvigu0AfQ zoYEG+CcLhcIQ== Received: from joabreu-VirtualBox.internal.synopsys.com (joabreu-e7440.internal.synopsys.com [10.107.19.26]) by mailhost.synopsys.com (Postfix) with ESMTP id D5A2C5DF1; Fri, 30 Nov 2018 01:47:41 -0800 (PST) From: Jose Abreu To: linux-snps-arc@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v3] ARC: io.h: Implement reads{x}()/writes{x}() Date: Fri, 30 Nov 2018 09:47:31 +0000 Message-Id: <244eba764469e8493f2d0c85a6d965aad6cd8128.1543571088.git.joabreu@synopsys.com> X-Mailer: git-send-email 1.9.1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181130_014754_879192_7B46F64E X-CRM114-Status: GOOD ( 11.05 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [198.182.47.9 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: linux-snps-arc@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux on Synopsys ARC Processors List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jose Abreu , Joao Pinto , Vineet Gupta , Alexey Brodkin , Vitor Soares , David Laight MIME-Version: 1.0 Sender: "linux-snps-arc" Errors-To: linux-snps-arc-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Some ARC CPU's do not support unaligned loads/stores. Currently, generic implementation of reads{b/w/l}()/writes{b/w/l}() is being used with ARC. This can lead to misfunction of some drivers as generic functions do a plain dereference of a pointer that can be unaligned. Let's use {get/put}_unaligned() helpers instead of plain dereference of pointer in order to fix. The helpers allow to get and store data from an unaligned address whilst preserving the CPU internal alignment. According to [1], the use of these helpers are costly in terms of performance so we added an initial check for a buffer already aligned so that the usage of the helpers can be avoided, when possible. [1] Documentation/unaligned-memory-access.txt Changes from v2: - Rework commit msg (Vineet) - Check if count is 0 and return (Vineet) - Use two different loops (Vineet) Changes from v1: - Check if buffer is already aligned (David) - Remove 64 bit mention (Alexey) Signed-off-by: Jose Abreu Tested-by: Vitor Soares Cc: Vineet Gupta Cc: Alexey Brodkin Cc: Joao Pinto Cc: Vitor Soares Cc: David Laight --- arch/arc/include/asm/io.h | 67 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h index c22b181e8206..6c89c31fbe15 100644 --- a/arch/arc/include/asm/io.h +++ b/arch/arc/include/asm/io.h @@ -12,6 +12,7 @@ #include #include #include +#include #ifdef CONFIG_ISA_ARCV2 #include @@ -94,6 +95,37 @@ static inline u32 __raw_readl(const volatile void __iomem *addr) return w; } +#define __raw_readsx(t,f) \ +static inline void __raw_reads##f(const volatile void __iomem *addr, \ + void *buffer, unsigned int count) \ +{ \ + bool is_aligned = ((unsigned long)buffer % ((t) / 8)) == 0; \ + u##t *buf = buffer; \ +\ + if (!count) \ + return; \ +\ + /* Some ARC CPU's don't support unaligned accesses */ \ + if (is_aligned) { \ + do { \ + u##t x = __raw_read##f(addr); \ + *buf++ = x; \ + } while (--count); \ + } else { \ + do { \ + u##t x = __raw_read##f(addr); \ + put_unaligned(x, buf++); \ + } while (--count); \ + } \ +} + +#define __raw_readsb __raw_readsb +__raw_readsx(8, b) +#define __raw_readsw __raw_readsw +__raw_readsx(16, w) +#define __raw_readsl __raw_readsl +__raw_readsx(32, l) + #define __raw_writeb __raw_writeb static inline void __raw_writeb(u8 b, volatile void __iomem *addr) { @@ -126,6 +158,35 @@ static inline void __raw_writel(u32 w, volatile void __iomem *addr) } +#define __raw_writesx(t,f) \ +static inline void __raw_writes##f(volatile void __iomem *addr, \ + const void *buffer, unsigned int count) \ +{ \ + bool is_aligned = ((unsigned long)buffer % ((t) / 8)) == 0; \ + const u##t *buf = buffer; \ +\ + if (!count) \ + return; \ +\ + /* Some ARC CPU's don't support unaligned accesses */ \ + if (is_aligned) { \ + do { \ + __raw_write##f(*buf++, addr); \ + } while (--count); \ + } else { \ + do { \ + __raw_write##f(get_unaligned(buf++), addr); \ + } while (--count); \ + } \ +} + +#define __raw_writesb __raw_writesb +__raw_writesx(8, b) +#define __raw_writesw __raw_writesw +__raw_writesx(16, w) +#define __raw_writesl __raw_writesl +__raw_writesx(32, l) + /* * MMIO can also get buffered/optimized in micro-arch, so barriers needed * Based on ARM model for the typical use case @@ -141,10 +202,16 @@ static inline void __raw_writel(u32 w, volatile void __iomem *addr) #define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) #define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) #define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) +#define readsb(p,d,l) ({ __raw_readsb(p,d,l); __iormb(); }) +#define readsw(p,d,l) ({ __raw_readsw(p,d,l); __iormb(); }) +#define readsl(p,d,l) ({ __raw_readsl(p,d,l); __iormb(); }) #define writeb(v,c) ({ __iowmb(); writeb_relaxed(v,c); }) #define writew(v,c) ({ __iowmb(); writew_relaxed(v,c); }) #define writel(v,c) ({ __iowmb(); writel_relaxed(v,c); }) +#define writesb(p,d,l) ({ __iowmb(); __raw_writesb(p,d,l); }) +#define writesw(p,d,l) ({ __iowmb(); __raw_writesw(p,d,l); }) +#define writesl(p,d,l) ({ __iowmb(); __raw_writesl(p,d,l); }) /* * Relaxed API for drivers which can handle barrier ordering themselves