From: grant.likely@secretlab.ca (Grant Likely)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 4/7] arm/devicetree: Reserve memory used by dtb blob
Date: Fri, 19 Feb 2010 12:27:45 -0700 [thread overview]
Message-ID: <20100219192734.15318.87375.stgit@angua> (raw)
In-Reply-To: <20100219185953.15318.4850.stgit@angua>
The device tree memory needs to be reserved as bootmem so that it doesn't
get overwritten by normal allocations later.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/arm/mm/init.c | 102 ++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 83 insertions(+), 19 deletions(-)
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index a340569..2ceb21b 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -17,6 +17,8 @@
#include <linux/initrd.h>
#include <linux/sort.h>
#include <linux/highmem.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
#include <asm/mach-types.h>
#include <asm/sections.h>
@@ -68,6 +70,20 @@ static int __init parse_tag_initrd2(const struct tag *tag)
__tagtable(ATAG_INITRD2, parse_tag_initrd2);
+#if defined(CONFIG_OF_FLATTREE)
+static unsigned long phys_devtree_start __initdata = 0;
+static unsigned long phys_devtree_size __initdata = 0;
+
+static int __init parse_tag_devtree(const struct tag *tag)
+{
+ phys_devtree_start = tag->u.devtree.start;
+ phys_devtree_size = tag->u.devtree.size;
+ return 0;
+}
+
+__tagtable(ATAG_DEVTREE, parse_tag_devtree);
+#endif
+
/*
* This keeps memory configuration data used by a couple memory
* initialization functions, as well as show_mem() for the skipping
@@ -191,29 +207,33 @@ find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
return bootmap_pfn;
}
-static int __init check_initrd(struct meminfo *mi)
+static int __init check_region(struct meminfo *mi,
+ unsigned long start, unsigned long size)
{
- int initrd_node = -2;
-#ifdef CONFIG_BLK_DEV_INITRD
- unsigned long end = phys_initrd_start + phys_initrd_size;
-
- /*
- * Make sure that the initrd is within a valid area of
- * memory.
- */
- if (phys_initrd_size) {
- unsigned int i;
+ unsigned long end = start + size - 1;
+ unsigned int i;
- initrd_node = -1;
+ if (!size)
+ return -2;
- for (i = 0; i < mi->nr_banks; i++) {
- struct membank *bank = &mi->bank[i];
- if (bank_phys_start(bank) <= phys_initrd_start &&
- end <= bank_phys_end(bank))
- initrd_node = bank->node;
- }
+ /* Make sure that the region is within a valid bank of memory. */
+ for (i = 0; i < mi->nr_banks; i++) {
+ struct membank *bank = &mi->bank[i];
+ if (bank_phys_start(bank) <= start &&
+ end <= bank_phys_end(bank))
+ return bank->node;
}
+ /* Region is outside of physical memory */
+ return -1;
+}
+
+static int __init check_initrd(struct meminfo *mi)
+{
+ int initrd_node = -2;
+
+#if defined(CONFIG_BLK_DEV_INITRD)
+ initrd_node = check_region(mi, phys_initrd_start, phys_initrd_size);
if (initrd_node == -1) {
printk(KERN_ERR "INITRD: 0x%08lx+0x%08lx extends beyond "
"physical memory - disabling initrd\n",
@@ -225,6 +245,27 @@ static int __init check_initrd(struct meminfo *mi)
return initrd_node;
}
+static int __init check_devtree(struct meminfo *mi)
+{
+ int node = -2;
+
+#if defined(CONFIG_OF_FLATTREE)
+ if ((phys_devtree_start == 0) || (phys_devtree_size == 0))
+ goto out;
+
+ node = check_region(mi, phys_devtree_start, phys_devtree_size);
+ if (node == -1) {
+ phys_devtree_start = phys_devtree_size = 0;
+ pr_err("DEVICETREE: 0x%08lx+0x%08lx extends beyond "
+ "physical memory - disabling device tree\n",
+ phys_devtree_start, phys_devtree_size);
+ }
+#endif
+
+ out:
+ return node;
+}
+
static inline void map_memory_bank(struct membank *bank)
{
#ifdef CONFIG_MMU
@@ -305,6 +346,25 @@ static void __init bootmem_reserve_initrd(int node)
#endif
}
+static void __init bootmem_reserve_devtree(int node)
+{
+#if defined(CONFIG_OF_FLATTREE)
+ pg_data_t *pgdat = NODE_DATA(node);
+ int res;
+
+ res = reserve_bootmem_node(pgdat, phys_devtree_start,
+ phys_devtree_size, BOOTMEM_EXCLUSIVE);
+ if (res) {
+ pr_err("DEVICETREE: 0x%08lx+0x%08lx overlaps in-use "
+ "memory region - disabling device tree\n",
+ phys_devtree_start, phys_devtree_size);
+ return;
+ }
+
+ initial_boot_params = (void *)__phys_to_virt(phys_devtree_start);
+#endif
+}
+
static void __init bootmem_free_node(int node, struct meminfo *mi)
{
unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
@@ -397,7 +457,7 @@ void __init bootmem_init(void)
{
struct meminfo *mi = &meminfo;
unsigned long min, max_low, max_high;
- int node, initrd_node;
+ int node, initrd_node, devtree_node;
sort(&mi->bank, mi->nr_banks, sizeof(mi->bank[0]), meminfo_cmp, NULL);
@@ -405,6 +465,7 @@ void __init bootmem_init(void)
* Locate which node contains the ramdisk image, if any.
*/
initrd_node = check_initrd(mi);
+ devtree_node = check_devtree(mi);
max_low = max_high = 0;
@@ -438,9 +499,12 @@ void __init bootmem_init(void)
/*
* If the initrd is in this node, reserve its memory.
+ * and do the same for the device tree blob
*/
if (node == initrd_node)
bootmem_reserve_initrd(node);
+ if (node == devtree_node)
+ bootmem_reserve_devtree(node);
/*
* Sparsemem tries to allocate bootmem in memory_present(),
next prev parent reply other threads:[~2010-02-19 19:27 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-19 19:26 [PATCH 0/7] Add basic ARM device tree support Grant Likely
2010-02-19 19:27 ` [PATCH 1/7] arm-dt: Add ATAG_DEVTREE tag Grant Likely
2010-02-19 19:27 ` [PATCH 2/7] arm-dt: Allow CONFIG_OF on ARM Grant Likely
2010-02-19 19:27 ` [PATCH 3/7] arm-dt: add devictree node reference to dev_archdata Grant Likely
2010-02-19 19:27 ` Grant Likely [this message]
2010-02-19 19:28 ` [PATCH 5/7] arm-dt: unflatten device tree Grant Likely
2010-02-19 19:29 ` [RFC/PATCH 6/7] arm/devicetree: Allow .dtb to be carried in the zImage payload Grant Likely
2010-02-19 19:29 ` [PATCH 7/7] arm/boot/hack: set uImage load address to 0x81000000 Grant Likely
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100219192734.15318.87375.stgit@angua \
--to=grant.likely@secretlab.ca \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).