From patchwork Fri Feb 28 13:42:47 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 25552 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qa0-f69.google.com (mail-qa0-f69.google.com [209.85.216.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 7F36820543 for ; Fri, 28 Feb 2014 13:43:41 +0000 (UTC) Received: by mail-qa0-f69.google.com with SMTP id w5sf1459522qac.4 for ; Fri, 28 Feb 2014 05:43: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: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:mime-version :errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list:content-type :content-transfer-encoding; bh=YDp8sB9iZoUWSpH7Y/GAAaxZEg1JdNu82BbtmptkapM=; b=mcOqBgFZhCnvzTbhE5BNUTKwaDsOTmaXiS2rZ0N5eUL93Yls6dZ259dBTFdKusJoK1 kPVKcUIghSEndGNDkQu5jn72R4JB/bYOhrt+Lh97OZByjB/412VpT2ryJK9EN4FXShB+ blnJS43FHzuaXDUYyMuLuCTruM1gZyi/6MogQL6B2H6hGbDfT9mzCvuqDOS1dACiLdWp xaJ+Tq4ucMH+uPWSxV39p6usUh8A88xNIsvlqsHeHG8CgLWf+o/EMeRPBFKogek7yzmL LkuCfXf+3JsqiSyggfsYZ4tHIu3tGiRWf34nxEQjxRGpKKg7A3khtAEQ8F8tOygyBSDo Wrsg== X-Gm-Message-State: ALoCoQnlZHzV+dRJpfC2u6dz7i8ITS1tVzIFmrKk1j9LftYi93V4UCTourmpuMlLIz/Fv1+ypNPH X-Received: by 10.58.136.100 with SMTP id pz4mr1245812veb.26.1393595021209; Fri, 28 Feb 2014 05:43:41 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.38.47 with SMTP id s44ls1108943qgs.70.gmail; Fri, 28 Feb 2014 05:43:41 -0800 (PST) X-Received: by 10.52.250.4 with SMTP id yy4mr30110vdc.56.1393595021070; Fri, 28 Feb 2014 05:43:41 -0800 (PST) Received: from mail-vc0-f170.google.com (mail-vc0-f170.google.com [209.85.220.170]) by mx.google.com with ESMTPS id fi9si1782106vcb.114.2014.02.28.05.43.41 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 28 Feb 2014 05:43:41 -0800 (PST) Received-SPF: neutral (google.com: 209.85.220.170 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.170; Received: by mail-vc0-f170.google.com with SMTP id hu8so730329vcb.29 for ; Fri, 28 Feb 2014 05:43:41 -0800 (PST) X-Received: by 10.52.23.68 with SMTP id k4mr13458776vdf.24.1393595020931; Fri, 28 Feb 2014 05:43:40 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.130.193 with SMTP id u1csp54591vcs; Fri, 28 Feb 2014 05:43:40 -0800 (PST) X-Received: by 10.181.12.16 with SMTP id em16mr3420094wid.3.1393595019884; Fri, 28 Feb 2014 05:43:39 -0800 (PST) Received: from ip-10-141-164-156.ec2.internal (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTPS id qf4si812149wic.36.2014.02.28.05.43.39 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Fri, 28 Feb 2014 05:43:39 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linaro-mm-sig-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Received: from localhost ([127.0.0.1] helo=ip-10-141-164-156.ec2.internal) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1WJNhZ-0008JM-QG; Fri, 28 Feb 2014 13:42:09 +0000 Received: from mailout1.w1.samsung.com ([210.118.77.11]) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1WJNhF-0008HG-6W for linaro-mm-sig@lists.linaro.org; Fri, 28 Feb 2014 13:41:49 +0000 Received: from eucpsbgm2.samsung.com (unknown [203.254.199.245]) by mailout1.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N1P00M0MKRZ3080@mailout1.w1.samsung.com> for linaro-mm-sig@lists.linaro.org; Fri, 28 Feb 2014 13:43:11 +0000 (GMT) X-AuditID: cbfec7f5-b7fc96d000004885-29-5310926e2c76 Received: from eusync3.samsung.com ( [203.254.199.213]) by eucpsbgm2.samsung.com (EUCPMTA) with SMTP id 02.BE.18565.E6290135; Fri, 28 Feb 2014 13:43:10 +0000 (GMT) Received: from amdc1339.mshome.net ([106.116.147.30]) by eusync3.samsung.com (Oracle Communications Messaging Server 7u4-23.01 (7.0.4.23.0) 64bit (built Aug 10 2011)) with ESMTPA id <0N1P002ZJKROU750@eusync3.samsung.com>; Fri, 28 Feb 2014 13:43:10 +0000 (GMT) From: Marek Szyprowski To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linaro-mm-sig@lists.linaro.org, devicetree@vger.kernel.org, linux-doc@vger.kernel.org Date: Fri, 28 Feb 2014 14:42:47 +0100 Message-id: <1393594976-16728-3-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1393594976-16728-1-git-send-email-m.szyprowski@samsung.com> References: <1393594976-16728-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAAyWRW0iTYRyHfbfvtNXwc6l8jbIwYiHmCS9ecklEyGthBYIXeVFTh0puypai EjRFZS5PTHKWps5D1NAZy9OWlhtDzbDSqSM8p12o0w5rUTYlx+6e/8Pzu/pTbL4GE1DZsnsS uUycE0pwsfcH43PnZRo6OWq7/wjc14yR8HtpORt+e1YFYKvtAw5rnTocjnqGAHRWqzBoMuwC OFXqJOFgZSMJf82usaBxfR6HuopODNrNzQTssS2R8OWmhQW7HNMs2DZehkOPNgROOlwE7LZ1 kLBO24PB8hEbCfcHjRjcslRgsLdxG4N6swfAzR8T2KUTqLulG6B/exqAtuvrALLXVLOQ6ckS iaqcZTgy6isJtDg/TKBXnQ/QwsE6G81OlOLI4Nliodr9KPTUXANQTZ8eIJcx5GbALa4oQ5KT XSCRR8bf4WYNt6qIvJHYwhLXGK4EM2FqwKEYOpaxGUpIHwczn5Z7CTXgUny6CzCGkia273jI YlabqljeiqCjGfWOmvByIK0DjKsF80ZseoVgVNO+6Bidysz1DByuKQqjzzKf2+O9mkcjxm6q Bl7N0KeZZo3Iqzl0IqPUruBe5h8mC38coA7w2oCfHgRJ8tPzFGmZ0pgIhViqyJdlRqTnSo3A 90f3EOgau2AFNAVCj/LqEv2T+bi4QFEktQKGYocG8jZK6WQ+L0NcVCyR596W5+dIFFbAojgC Jbi+kzB/Kumcqb6vwc0ZTBMYhLrIvccXE9bDA3ln4lIDCkfFFVP9weHla/etk6JBm+NvvWCx N69FSD6KX08RpdS+aFxeDngttp3kqmJGcb/WuN0Gz++3lqDVrw1XlR3P1Zb0n1eK32x8FGrN EZfdwiR/zrtM/sy1G/bjd9vdA19CMUWWODqMLVeI/wPn6ImxpQIAAA== Cc: Mark Rutland , Benjamin Herrenschmidt , Tomasz Figa , Will Deacon , Tomasz Figa , Paul Mackerras , Arnd Bergmann , Josh Cartwright , Catalin Marinas , Grant Likely , Ian Campbell , Pawel Moll , Stephen Warren , Sascha Hauer , Michal Nazarewicz , Rob Herring , Kumar Gala , Olof Johansson Subject: [Linaro-mm-sig] [PATCH v6 02/11] drivers: of: add initialization code for static reserved memory X-BeenThere: linaro-mm-sig@lists.linaro.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: linaro-mm-sig-bounces@lists.linaro.org Sender: linaro-mm-sig-bounces@lists.linaro.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: m.szyprowski@samsung.com X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.170 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) 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 This patch adds support for static (defined by 'reg' property) reserved memory regions declared in device tree. Memory blocks can be reliably reserved only during early boot. This must happen before the whole memory management subsystem is initialized, because we need to ensure that the given contiguous blocks are not yet allocated by kernel. Also it must happen before kernel mappings for the whole low memory are created, to ensure that there will be no mappings (for reserved blocks). Typically, all this happens before device tree structures are unflattened, so we need to get reserved memory layout directly from fdt. Based on previous code provided by Josh Cartwright Signed-off-by: Marek Szyprowski Acked-by: Grant Likely --- drivers/of/fdt.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/of_fdt.h | 3 ++ 2 files changed, 134 insertions(+) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 758b4f8b30b7..819e11209718 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -440,6 +441,118 @@ struct boot_param_header *initial_boot_params; #ifdef CONFIG_OF_EARLY_FLATTREE /** + * res_mem_reserve_reg() - reserve all memory described in 'reg' property + */ +static int __init __reserved_mem_reserve_reg(unsigned long node, + const char *uname) +{ + int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32); + phys_addr_t base, size; + unsigned long len; + __be32 *prop; + int nomap; + + prop = of_get_flat_dt_prop(node, "reg", &len); + if (!prop) + return -ENOENT; + + if (len && len % t_len != 0) { + pr_err("Reserved memory: invalid reg property in '%s', skipping node.\n", + uname); + return -EINVAL; + } + + nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL; + + while (len >= t_len) { + base = dt_mem_next_cell(dt_root_addr_cells, &prop); + size = dt_mem_next_cell(dt_root_size_cells, &prop); + + if (base && size && + early_init_dt_reserve_memory_arch(base, size, nomap) == 0) + pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n", + uname, &base, (unsigned long)size / SZ_1M); + else + pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %ld MiB\n", + uname, &base, (unsigned long)size / SZ_1M); + + len -= t_len; + } + return 0; +} + +/** + * __reserved_mem_check_root() - check if #size-cells, #address-cells provided + * in /reserved-memory matches the values supported by the current implementation, + * also check if ranges property has been provided + */ +static int __reserved_mem_check_root(unsigned long node) +{ + __be32 *prop; + + prop = of_get_flat_dt_prop(node, "#size-cells", NULL); + if (!prop || be32_to_cpup(prop) != dt_root_size_cells) + return -EINVAL; + + prop = of_get_flat_dt_prop(node, "#address-cells", NULL); + if (!prop || be32_to_cpup(prop) != dt_root_addr_cells) + return -EINVAL; + + prop = of_get_flat_dt_prop(node, "ranges", NULL); + if (!prop) + return -EINVAL; + return 0; +} + +/** + * fdt_scan_reserved_mem() - scan a single FDT node for reserved memory + */ +static int __init __fdt_scan_reserved_mem(unsigned long node, const char *uname, + int depth, void *data) +{ + static int found; + const char *status; + + if (!found && depth == 1 && strcmp(uname, "reserved-memory") == 0) { + if (__reserved_mem_check_root(node) != 0) { + pr_err("Reserved memory: unsupported node format, ignoring\n"); + /* break scan */ + return 1; + } + found = 1; + /* scan next node */ + return 0; + } else if (!found) { + /* scan next node */ + return 0; + } else if (found && depth < 2) { + /* scanning of /reserved-memory has been finished */ + return 1; + } + + status = of_get_flat_dt_prop(node, "status", NULL); + if (status && strcmp(status, "okay") != 0 && strcmp(status, "ok") != 0) + return 0; + + __reserved_mem_reserve_reg(node, uname); + + /* scan next node */ + return 0; +} + +/** + * early_init_fdt_scan_reserved_mem() - create reserved memory regions + * + * This function grabs memory from early allocator for device exclusive use + * defined in device tree structures. It should be called by arch specific code + * once the early allocator (i.e. memblock) has been fully activated. + */ +void __init early_init_fdt_scan_reserved_mem(void) +{ + of_scan_flat_dt(__fdt_scan_reserved_mem, NULL); +} + +/** * of_scan_flat_dt - scan flattened tree blob and call callback on each. * @it: callback function * @data: context data pointer @@ -856,6 +969,16 @@ void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size) memblock_add(base, size); } +int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base, + phys_addr_t size, bool nomap) +{ + if (memblock_is_region_reserved(base, size)) + return -EBUSY; + if (nomap) + return memblock_remove(base, size); + return memblock_reserve(base, size); +} + /* * called from unflatten_device_tree() to bootstrap devicetree itself * Architectures can override this definition if memblock isn't used @@ -864,6 +987,14 @@ void * __init __weak early_init_dt_alloc_memory_arch(u64 size, u64 align) { return __va(memblock_alloc(size, align)); } +#else +int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base, + phys_addr_t size, bool nomap) +{ + pr_err("Reserved memory not supported, ignoring range 0x%llx - 0x%llx%s\n", + base, size, nomap ? " (nomap)" : ""); + return -ENOSYS; +} #endif bool __init early_init_dt_scan(void *params) diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index 2b77058a7335..8610ad8d77d2 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h @@ -98,7 +98,10 @@ extern int early_init_dt_scan_chosen(unsigned long node, const char *uname, int depth, void *data); extern int early_init_dt_scan_memory(unsigned long node, const char *uname, int depth, void *data); +extern void early_init_fdt_scan_reserved_mem(void); extern void early_init_dt_add_memory_arch(u64 base, u64 size); +extern int early_init_dt_reserve_memory_arch(phys_addr_t base, phys_addr_t size, + bool no_map); extern void * early_init_dt_alloc_memory_arch(u64 size, u64 align); extern u64 dt_mem_next_cell(int s, __be32 **cellp);