From patchwork Wed Dec 10 05:25:22 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 419415 X-Patchwork-Delegate: albert.aribaud@free.fr Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 07F5A1400D5 for ; Wed, 10 Dec 2014 16:28:19 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 8C18F4B764; Wed, 10 Dec 2014 06:27:51 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id o27xDAlL-29t; Wed, 10 Dec 2014 06:27:51 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 747D24B76A; Wed, 10 Dec 2014 06:26:38 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 2B9FA4B6B1 for ; Wed, 10 Dec 2014 06:25:52 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7VkaUVEqYXrF for ; Wed, 10 Dec 2014 06:25:52 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-pd0-f202.google.com (mail-pd0-f202.google.com [209.85.192.202]) by theia.denx.de (Postfix) with ESMTPS id B75E74B6BB for ; Wed, 10 Dec 2014 06:25:43 +0100 (CET) Received: by mail-pd0-f202.google.com with SMTP id v10so336260pde.5 for ; Tue, 09 Dec 2014 21:25:41 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=K4Foq+bKKD8TWiBY+iJWMNUp/pHz42PX7BB/1G0vQdM=; b=LP7H5VZCVIS3PkiOK9SQiHtBBw7z5sy4coQi1B6DB8qA8VIq2FE0jk9m0WXjpFcFlK d2cGr5/8P9E2j97m3gmcp8QW8OYerfUSpSQhTqYufYUOs0s1vEIaRdEi1AKnle1zKyDL 6wk6oAiIwB/NUb3of7G7MN6kKpEt8FszX+F/XvY8m0dEYkcydo0wFqvZCUt9j49WUUY4 hTeK5urMiOWRqCuNA7MtBFgqYYJ7ndtFHMjPDGZZnSu9tbvx+8JVk3XsnXCuSlxxrpgH vH9zNkm318FEYSPWikWtj1wVfwXxFTjEk63oz3EqX/jtnay7Hoas2oJdz7t+Mf/raJ2b KRjw== X-Gm-Message-State: ALoCoQltouKcazz/X+qY10XDxIHnNIl942zzohst5qjFXtWwlWIfUYcdzARQJjQ/qjjYrpU0VE2Y X-Received: by 10.70.53.33 with SMTP id y1mr2228681pdo.3.1418189141285; Tue, 09 Dec 2014 21:25:41 -0800 (PST) Received: from corpmail-nozzle1-2.hot.corp.google.com ([100.108.1.103]) by gmr-mx.google.com with ESMTPS id t28si114353yhb.4.2014.12.09.21.25.40 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Dec 2014 21:25:41 -0800 (PST) Received: from kaki.bld.corp.google.com ([172.29.216.32]) by corpmail-nozzle1-2.hot.corp.google.com with ESMTP id 0Z26zj1s.2; Tue, 09 Dec 2014 21:25:41 -0800 Received: by kaki.bld.corp.google.com (Postfix, from userid 121222) id 982762213FE; Tue, 9 Dec 2014 22:25:40 -0700 (MST) From: Simon Glass To: U-Boot Mailing List Date: Tue, 9 Dec 2014 22:25:22 -0700 Message-Id: <1418189127-27407-19-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 2.2.0.rc0.207.ga3a616c In-Reply-To: <1418189127-27407-1-git-send-email-sjg@chromium.org> References: <1418189127-27407-1-git-send-email-sjg@chromium.org> Cc: Thierry Reding Subject: [U-Boot] [PATCH v4 18/23] ARM: Implement non-cached memory support X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.13 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de From: Thierry Reding Implement an API that can be used by drivers to allocate memory from a pool that is mapped uncached. This is useful if drivers would otherwise need to do extensive cache maintenance (or explicitly maintaining the cache isn't safe). The API is protected using the new CONFIG_SYS_NONCACHED_MEMORY setting. Boards can set this to the size to be used for the non-cached area. The area will typically be right below the malloc() area, but architectures should take care of aligning the beginning and end of the area to honor any mapping restrictions. Architectures must also ensure that mappings established for this area do not overlap with the malloc() area (which should remain cached for improved performance). While the API is currently only implemented for ARM v7, it should be generic enough to allow other architectures to implement it as well. Signed-off-by: Thierry Reding Signed-off-by: Simon Glass --- Changes in v4: None Changes in v3: - Avoid build error with noncached_init() when the dcache is disabled README | 19 +++++++++++++++++++ arch/arm/include/asm/system.h | 5 +++++ arch/arm/lib/cache.c | 44 +++++++++++++++++++++++++++++++++++++++++++ common/board_r.c | 11 +++++++++++ 4 files changed, 79 insertions(+) diff --git a/README b/README index 4ca04d0..5af345b 100644 --- a/README +++ b/README @@ -4007,6 +4007,25 @@ Configuration Settings: boards which do not use the full malloc in SPL (which is enabled with CONFIG_SYS_SPL_MALLOC_START). +- CONFIG_SYS_NONCACHED_MEMORY: + Size of non-cached memory area. This area of memory will be + typically located right below the malloc() area and mapped + uncached in the MMU. This is useful for drivers that would + otherwise require a lot of explicit cache maintenance. For + some drivers it's also impossible to properly maintain the + cache. For example if the regions that need to be flushed + are not a multiple of the cache-line size, *and* padding + cannot be allocated between the regions to align them (i.e. + if the HW requires a contiguous array of regions, and the + size of each region is not cache-aligned), then a flush of + one region may result in overwriting data that hardware has + written to another region in the same cache-line. This can + happen for example in network drivers where descriptors for + buffers are typically smaller than the CPU cache-line (e.g. + 16 bytes vs. 32 or 64 bytes). + + Non-cached memory is only supported on 32-bit ARM at present. + - CONFIG_SYS_BOOTM_LEN: Normally compressed uImages are limited to an uncompressed size of 8 MBytes. If this is not enough, diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 61e2914..89f2294 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -212,6 +212,11 @@ void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size, */ void mmu_page_table_flush(unsigned long start, unsigned long stop); +#ifdef CONFIG_SYS_NONCACHED_MEMORY +void noncached_init(void); +phys_addr_t noncached_alloc(size_t size, size_t align); +#endif /* CONFIG_SYS_NONCACHED_MEMORY */ + #endif /* __ASSEMBLY__ */ #define arch_align_stack(x) (x) diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c index f1c0792..9cedeac 100644 --- a/arch/arm/lib/cache.c +++ b/arch/arm/lib/cache.c @@ -8,6 +8,7 @@ /* for now: just dummy functions to satisfy the linker */ #include +#include __weak void flush_cache(unsigned long start, unsigned long size) { @@ -49,3 +50,46 @@ __weak void enable_caches(void) { puts("WARNING: Caches not enabled\n"); } + +#ifdef CONFIG_SYS_NONCACHED_MEMORY +/* + * Reserve one MMU section worth of address space below the malloc() area that + * will be mapped uncached. + */ +static unsigned long noncached_start; +static unsigned long noncached_end; +static unsigned long noncached_next; + +void noncached_init(void) +{ + phys_addr_t start, end; + size_t size; + + end = ALIGN(mem_malloc_start, MMU_SECTION_SIZE) - MMU_SECTION_SIZE; + size = ALIGN(CONFIG_SYS_NONCACHED_MEMORY, MMU_SECTION_SIZE); + start = end - size; + + debug("mapping memory %pa-%pa non-cached\n", &start, &end); + + noncached_start = start; + noncached_end = end; + noncached_next = start; + +#ifndef CONFIG_SYS_DCACHE_OFF + mmu_set_region_dcache_behaviour(noncached_start, size, DCACHE_OFF); +#endif +} + +phys_addr_t noncached_alloc(size_t size, size_t align) +{ + phys_addr_t next = ALIGN(noncached_next, align); + + if (next >= noncached_end || (noncached_end - next) < size) + return 0; + + debug("allocated %zu bytes of uncached memory @%pa\n", size, &next); + noncached_next = next + size; + + return next; +} +#endif /* CONFIG_SYS_NONCACHED_MEMORY */ diff --git a/common/board_r.c b/common/board_r.c index 4eb7a02..a301cc2 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -265,6 +265,14 @@ static int initr_malloc(void) return 0; } +#ifdef CONFIG_SYS_NONCACHED_MEMORY +static int initr_noncached(void) +{ + noncached_init(); + return 0; +} +#endif + #ifdef CONFIG_DM static int initr_dm(void) { @@ -687,6 +695,9 @@ init_fnc_t init_sequence_r[] = { #endif initr_barrier, initr_malloc, +#ifdef CONFIG_SYS_NONCACHED_MEMORY + initr_noncached, +#endif bootstage_relocate, #ifdef CONFIG_DM initr_dm,