LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH v2 0/6] Basic ARM device support
@ 2011-01-31 21:03 Grant Likely
  2011-01-31 21:03 ` [PATCH v2 1/6] arm/dt: Make __vet_atags also accept a dtb image Grant Likely
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Grant Likely @ 2011-01-31 21:03 UTC (permalink / raw)
  To: nicolas.pitre, Russell King, Catalin Marinas, devicetree-discuss,
	linux-kernel, buytenh, Olof Johansson, john.linn,
	linux-arm-kernel

Second posting.  v2 reworks the handling of the dtb during early init.
Instead of trying to reserve the memory region containing the dtb,
this version instead copies it into an allocated buffer because the
dtb may have been loaded by firmware into an unsafe region (like the
interrupt vectors at the base of RAM).  Nicolas, can you please
take a look at patch #4 and commenting on whether or not I'm
handling it safely?

Once again, I'm not looking to get these patches merged into mainline
yet.

...

This patch series allows CONFIG_OF to be enabled on ARM and allows the
kernel to accept a dtb pointer from boot firmware instead of atags.
If a dtb is passed, then the kernel will use the root 'compatible'
property to find a matching machine_desc, and it will use it to obtain
the memory layout, initrd location and kernel parameters string.

Only limited device tree support is enabled here.  It does not perform
any kind of device registration from device tree data.  That support
will be enabled in a later patch set.  Rather, this series is a stable
base that other engineers can use to start working on device tree
support for their platforms.

Tested on Versatile (qemu) and nVidia Tegra Harmony.  Kernel compiles
an boot with CONFIG_OF both on and off, both with and without passing
a device tree blob.

This series is reflected in the following branch:

 git://git.secretlab.ca/git/linux-2.6 devicetree/arm

The 'clean' patches (rebased) can be found here:

 git://git.secretlab.ca/git/linux-2.6 devicetree/test

The way I've managed the devicetree/test branch in the past has made
it hard for other engineers to work with the device tree support, so
I'm changing the way I'm handling it.  I will *not* rebase this new
branch.  My intention is to keep it in essentially 'merge-ready' state
at all times.  ie. I'm only going to put patches into this branch that
I consider complete and are required to enable arm device tree
support.  ie. core dt infrastructure and dt board support.  Device
drivers should be submitted directly to their respective
lists/maintainers.  I'll also be soliciting acks from platform
maintainers before I pick up board support patches into this branch.

Cheers,
g.


---

Grant Likely (5):
      arm/dt: Make __vet_atags also accept a dtb image
      arm/dt: consolidate atags setup into setup_machine_atags
      arm/dt: probe for platforms via the device tree
      arm/dt: Basic versatile devicetree support
      arm/dt: Basic tegra devicetree support

Jeremy Kerr (1):
      arm/dt: Allow CONFIG_OF on ARM


 arch/arm/Kconfig                       |    7 ++
 arch/arm/include/asm/mach/arch.h       |    2 
 arch/arm/include/asm/prom.h            |   36 +++++++++
 arch/arm/include/asm/setup.h           |    3 +
 arch/arm/kernel/Makefile               |    1 
 arch/arm/kernel/devtree.c              |  134 ++++++++++++++++++++++++++++++++
 arch/arm/kernel/head-common.S          |   24 ++++--
 arch/arm/kernel/head.S                 |    8 +-
 arch/arm/kernel/setup.c                |   78 ++++++++++---------
 arch/arm/mach-tegra/board-harmony.c    |    6 +
 arch/arm/mach-tegra/gpio.c             |    4 -
 arch/arm/mach-versatile/versatile_ab.c |    6 +
 arch/arm/mach-versatile/versatile_pb.c |    6 +
 arch/arm/mm/init.c                     |    8 ++
 14 files changed, 276 insertions(+), 47 deletions(-)
 create mode 100644 arch/arm/include/asm/prom.h
 create mode 100644 arch/arm/kernel/devtree.c

-- 
Signature

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/6] arm/dt: Make __vet_atags also accept a dtb image
  2011-01-31 21:03 [PATCH v2 0/6] Basic ARM device support Grant Likely
@ 2011-01-31 21:03 ` Grant Likely
  2011-01-31 21:04 ` [PATCH v2 2/6] arm/dt: Allow CONFIG_OF on ARM Grant Likely
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Grant Likely @ 2011-01-31 21:03 UTC (permalink / raw)
  To: nicolas.pitre, Russell King, Catalin Marinas, devicetree-discuss,
	linux-kernel, buytenh, Olof Johansson, john.linn,
	linux-arm-kernel

The dtb is passed to the kernel via register r2, which is the same
method that is used to pass an atags pointer.  This patch modifies
__vet_atags to not clear r2 when it encounters a dtb image.

v2: fixed bugs pointed out by Nicolas Pitre

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
 arch/arm/kernel/head-common.S |   24 ++++++++++++++++++------
 arch/arm/kernel/head.S        |    8 ++++----
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 8f57515..882c292 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -15,6 +15,12 @@
 #define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
 #define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2)
 
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define OF_DT_MAGIC 0xd00dfeed
+#else
+#define OF_DT_MAGIC 0xedfe0dd0 /* 0xd00dfeed in big-endian */
+#endif
+
 /*
  * Exception handling.  Something went wrong and we can't proceed.  We
  * ought to tell the user, but since we don't have any guarantee that
@@ -105,22 +111,28 @@ __lookup_machine_type_data:
 
 /* Determine validity of the r2 atags pointer.  The heuristic requires
  * that the pointer be aligned, in the first 16k of physical RAM and
- * that the ATAG_CORE marker is first and present.  Future revisions
+ * that the ATAG_CORE marker is first and present.  If CONFIG_OF_FLATTREE
+ * is selected, then it will also accept a dtb pointer.  Future revisions
  * of this function may be more lenient with the physical address and
  * may also be able to move the ATAGS block if necessary.
  *
  * r8  = machinfo
  *
  * Returns:
- *  r2 either valid atags pointer, or zero
+ *  r2 either valid atags pointer, valid dtb pointer, or zero
  *  r5, r6 corrupted
  */
 __vet_atags:
 	tst	r2, #0x3			@ aligned?
 	bne	1f
 
-	ldr	r5, [r2, #0]			@ is first tag ATAG_CORE?
-	cmp	r5, #ATAG_CORE_SIZE
+	ldr	r5, [r2, #0]
+#ifdef CONFIG_OF_FLATTREE
+	ldr	r6, =OF_DT_MAGIC		@ is it a DTB?
+	cmp	r5, r6
+	beq	2f
+#endif
+	cmp	r5, #ATAG_CORE_SIZE		@ is first tag ATAG_CORE?
 	cmpne	r5, #ATAG_CORE_SIZE_EMPTY
 	bne	1f
 	ldr	r5, [r2, #4]
@@ -128,7 +140,7 @@ __vet_atags:
 	cmp	r5, r6
 	bne	1f
 
-	mov	pc, lr				@ atag pointer is ok
+2:	mov	pc, lr				@ atag/dtb pointer is ok
 
 1:	mov	r2, #0
 	mov	pc, lr
@@ -140,7 +152,7 @@ ENDPROC(__vet_atags)
  *
  *  r0  = cp#15 control register
  *  r1  = machine ID
- *  r2  = atags pointer
+ *  r2  = atags/dtb pointer
  *  r9  = processor ID
  */
 	__INIT
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index f17d9a0..65d9489 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -66,7 +66,7 @@
  *
  * This is normally called from the decompressor code.  The requirements
  * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
- * r1 = machine nr, r2 = atags pointer.
+ * r1 = machine nr, r2 = atags or dtb pointer.
  *
  * This code is mostly position independent, so if you link the kernel at
  * 0xc0008000, you call this at __pa(0xc0008000).
@@ -93,7 +93,7 @@ ENTRY(stext)
 	beq	__error_a			@ yes, error 'a'
 
 	/*
-	 * r1 = machine no, r2 = atags,
+	 * r1 = machine no, r2 = atags or dtb,
 	 * r8 = machinfo, r9 = cpuid, r10 = procinfo
 	 */
 	bl	__vet_atags
@@ -335,7 +335,7 @@ __secondary_data:
  *
  *  r0  = cp#15 control register
  *  r1  = machine ID
- *  r2  = atags pointer
+ *  r2  = atags or dtb pointer
  *  r4  = page table pointer
  *  r9  = processor ID
  *  r13 = *virtual* address to jump to upon completion
@@ -372,7 +372,7 @@ ENDPROC(__enable_mmu)
  *
  *  r0  = cp#15 control register
  *  r1  = machine ID
- *  r2  = atags pointer
+ *  r2  = atags or dtb pointer
  *  r9  = processor ID
  *  r13 = *virtual* address to jump to upon completion
  *


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 2/6] arm/dt: Allow CONFIG_OF on ARM
  2011-01-31 21:03 [PATCH v2 0/6] Basic ARM device support Grant Likely
  2011-01-31 21:03 ` [PATCH v2 1/6] arm/dt: Make __vet_atags also accept a dtb image Grant Likely
@ 2011-01-31 21:04 ` Grant Likely
  2011-01-31 21:04 ` [PATCH v2 3/6] arm/dt: consolidate atags setup into setup_machine_atags Grant Likely
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Grant Likely @ 2011-01-31 21:04 UTC (permalink / raw)
  To: nicolas.pitre, Russell King, Catalin Marinas, devicetree-discuss,
	linux-kernel, buytenh, Olof Johansson, john.linn,
	linux-arm-kernel

From: Jeremy Kerr <jeremy.kerr@canonical.com>

Add some basic empty infrastructure for DT support on ARM.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
 arch/arm/Kconfig             |    7 ++++++
 arch/arm/include/asm/prom.h  |   25 ++++++++++++++++++++++
 arch/arm/include/asm/setup.h |    2 ++
 arch/arm/kernel/Makefile     |    1 +
 arch/arm/kernel/devtree.c    |   47 ++++++++++++++++++++++++++++++++++++++++++
 arch/arm/kernel/setup.c      |    2 +-
 6 files changed, 83 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/include/asm/prom.h
 create mode 100644 arch/arm/kernel/devtree.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5cff165..d8a330f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1586,6 +1586,13 @@ endmenu
 
 menu "Boot options"
 
+config USE_OF
+	bool "Flattened Device Tree support"
+	select OF
+	select OF_EARLY_FLATTREE
+	help
+	  Include support for flattened device tree machine descriptions.
+
 # Compressed boot loader in ROM.  Yes, we really want to ask about
 # TEXT and BSS so we preserve their values in the config files.
 config ZBOOT_ROM_TEXT
diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h
new file mode 100644
index 0000000..8f1037f
--- /dev/null
+++ b/arch/arm/include/asm/prom.h
@@ -0,0 +1,25 @@
+/*
+ *  arch/arm/include/asm/prom.h
+ *
+ *  Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef __ASMARM_PROM_H
+#define __ASMARM_PROM_H
+
+#ifdef CONFIG_OF
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+static inline void irq_dispose_mapping(unsigned int virq)
+{
+	return;
+}
+
+#endif /* CONFIG_OF */
+#endif /* ASMARM_PROM_H */
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index f1e5a9b..06c4d0e 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -221,6 +221,8 @@ extern struct meminfo meminfo;
 #define bank_phys_end(bank)	((bank)->start + (bank)->size)
 #define bank_phys_size(bank)	(bank)->size
 
+extern int arm_add_memory(unsigned long start, unsigned long size);
+
 #endif  /*  __KERNEL__  */
 
 #endif
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 185ee82..8df05fd 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_ARM_THUMBEE)	+= thumbee.o
 obj-$(CONFIG_KGDB)		+= kgdb.o
 obj-$(CONFIG_ARM_UNWIND)	+= unwind.o
 obj-$(CONFIG_HAVE_TCM)		+= tcm.o
+obj-$(CONFIG_OF)		+= devtree.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
 obj-$(CONFIG_SWP_EMULATE)	+= swp_emulate.o
 CFLAGS_swp_emulate.o		:= -Wa,-march=armv7-a
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
new file mode 100644
index 0000000..ac48da2
--- /dev/null
+++ b/arch/arm/kernel/devtree.c
@@ -0,0 +1,47 @@
+/*
+ *  linux/arch/arm/kernel/devtree.c
+ *
+ *  Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+
+#include <asm/setup.h>
+#include <asm/page.h>
+
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+	arm_add_memory(base, size);
+}
+
+void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+	return __va(memblock_alloc(size, align));
+}
+
+/**
+ * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq#
+ *
+ * Currently the mapping mechanism is trivial; simple flat hwirq numbers are
+ * mapped 1:1 onto Linux irq numbers.  Cascaded irq controllers are not
+ * supported.
+ */
+unsigned int irq_create_of_mapping(struct device_node *controller,
+				   const u32 *intspec, unsigned int intsize)
+{
+	return intspec[0];
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 420b8d6..d211609 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -443,7 +443,7 @@ static struct machine_desc * __init setup_machine(unsigned int nr)
 	return list;
 }
 
-static int __init arm_add_memory(unsigned long start, unsigned long size)
+int __init arm_add_memory(unsigned long start, unsigned long size)
 {
 	struct membank *bank = &meminfo.bank[meminfo.nr_banks];
 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 3/6] arm/dt: consolidate atags setup into setup_machine_atags
  2011-01-31 21:03 [PATCH v2 0/6] Basic ARM device support Grant Likely
  2011-01-31 21:03 ` [PATCH v2 1/6] arm/dt: Make __vet_atags also accept a dtb image Grant Likely
  2011-01-31 21:04 ` [PATCH v2 2/6] arm/dt: Allow CONFIG_OF on ARM Grant Likely
@ 2011-01-31 21:04 ` Grant Likely
  2011-01-31 21:04 ` [PATCH v2 4/6] arm/dt: probe for platforms via the device tree Grant Likely
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Grant Likely @ 2011-01-31 21:04 UTC (permalink / raw)
  To: nicolas.pitre, Russell King, Catalin Marinas, devicetree-discuss,
	linux-kernel, buytenh, Olof Johansson, john.linn,
	linux-arm-kernel

In preparation for adding device tree support, this patch consolidates
all of the atag-specific setup into a single function.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
 arch/arm/kernel/setup.c |   68 ++++++++++++++++++++++++-----------------------
 1 files changed, 35 insertions(+), 33 deletions(-)

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index d211609..cbc1836 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -424,25 +424,6 @@ void cpu_init(void)
 	    : "r14");
 }
 
-static struct machine_desc * __init setup_machine(unsigned int nr)
-{
-	struct machine_desc *list;
-
-	/*
-	 * locate machine in the list of supported machines.
-	 */
-	list = lookup_machine_type(nr);
-	if (!list) {
-		printk("Machine configuration botched (nr %d), unable "
-		       "to continue.\n", nr);
-		while (1);
-	}
-
-	printk("Machine: %s\n", list->name);
-
-	return list;
-}
-
 int __init arm_add_memory(unsigned long start, unsigned long size)
 {
 	struct membank *bank = &meminfo.bank[meminfo.nr_banks];
@@ -796,21 +777,23 @@ static void __init squash_mem_tags(struct tag *tag)
 			tag->hdr.tag = ATAG_NONE;
 }
 
-void __init setup_arch(char **cmdline_p)
+static struct machine_desc * __init setup_machine_tags(unsigned int nr)
 {
 	struct tag *tags = (struct tag *)&init_tags;
 	struct machine_desc *mdesc;
 	char *from = default_command_line;
 
-	unwind_init();
-
-	setup_processor();
-	mdesc = setup_machine(machine_arch_type);
-	machine_desc = mdesc;
-	machine_name = mdesc->name;
+	/*
+	 * locate machine in the list of supported machines.
+	 */
+	mdesc = lookup_machine_type(nr);
+	if (!mdesc) {
+		printk("Machine configuration botched (nr %d), unable "
+		       "to continue.\n", nr);
+		while (1);
+	}
 
-	if (mdesc->soft_reboot)
-		reboot_setup("s");
+	printk("Machine: %s\n", mdesc->name);
 
 	if (__atags_pointer)
 		tags = phys_to_virt(__atags_pointer);
@@ -838,16 +821,35 @@ void __init setup_arch(char **cmdline_p)
 		parse_tags(tags);
 	}
 
-	init_mm.start_code = (unsigned long) _text;
-	init_mm.end_code   = (unsigned long) _etext;
-	init_mm.end_data   = (unsigned long) _edata;
-	init_mm.brk	   = (unsigned long) _end;
-
 	/* parse_early_param needs a boot_command_line */
 	strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
 
 	/* populate cmd_line too for later use, preserving boot_command_line */
 	strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
+
+	return mdesc;
+}
+
+
+void __init setup_arch(char **cmdline_p)
+{
+	struct machine_desc *mdesc;
+
+	unwind_init();
+
+	setup_processor();
+	mdesc = setup_machine_tags(machine_arch_type);
+	machine_desc = mdesc;
+	machine_name = mdesc->name;
+
+	if (mdesc->soft_reboot)
+		reboot_setup("s");
+
+	init_mm.start_code = (unsigned long) _text;
+	init_mm.end_code   = (unsigned long) _etext;
+	init_mm.end_data   = (unsigned long) _edata;
+	init_mm.brk	   = (unsigned long) _end;
+
 	*cmdline_p = cmd_line;
 
 	parse_early_param();


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 4/6] arm/dt: probe for platforms via the device tree
  2011-01-31 21:03 [PATCH v2 0/6] Basic ARM device support Grant Likely
                   ` (2 preceding siblings ...)
  2011-01-31 21:04 ` [PATCH v2 3/6] arm/dt: consolidate atags setup into setup_machine_atags Grant Likely
@ 2011-01-31 21:04 ` Grant Likely
  2011-01-31 22:27   ` Nicolas Pitre
  2011-01-31 21:04 ` [PATCH v2 5/6] arm/dt: Basic versatile devicetree support Grant Likely
  2011-01-31 21:04 ` [PATCH v2 6/6] arm/dt: Basic tegra " Grant Likely
  5 siblings, 1 reply; 9+ messages in thread
From: Grant Likely @ 2011-01-31 21:04 UTC (permalink / raw)
  To: nicolas.pitre, Russell King, Catalin Marinas, devicetree-discuss,
	linux-kernel, buytenh, Olof Johansson, john.linn,
	linux-arm-kernel

If a dtb is passed to the kernel then the kernel needs to iterate
through compiled-in mdescs looking for one that matches and move the
dtb data to a safe location before it gets accidentally overwritten by
the kernel.

This patch creates a new function, setup_machine_fdt() which is
analogous to the setup_machine_atags() created in the previous patch.
It does all the early setup needed to use a device tree machine
description.  It also creates arm_unflatten_device_tree() which copies
the dtb into an allocated buffer and unflattens it into the live-tree
representation.

v2: Changed to save the dtb by copying into an allocated buffer.
    - Since the dtb will very likely be passed in the first 16k of ram
      where the interrupt vectors live, memblock_reserve() is
      insufficient to protect the dtb data.
[based on work originally written by Jeremy Kerr <jeremy.kerr@canonical.com>]
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
 arch/arm/include/asm/mach/arch.h |    2 +
 arch/arm/include/asm/prom.h      |   11 +++++
 arch/arm/include/asm/setup.h     |    1 
 arch/arm/kernel/devtree.c        |   87 ++++++++++++++++++++++++++++++++++++++
 arch/arm/kernel/setup.c          |   10 +++-
 arch/arm/mm/init.c               |    8 +++
 6 files changed, 117 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index 3a0893a..2ed24e7 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -22,6 +22,8 @@ struct machine_desc {
 	unsigned int		nr;		/* architecture number	*/
 	const char		*name;		/* architecture name	*/
 	unsigned long		boot_params;	/* tagged list		*/
+	const char		**dt_compat;	/* array of device tree
+						 * 'compatible' strings	*/
 
 	unsigned int		nr_irqs;	/* number of IRQs */
 
diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h
index 8f1037f..6ba62a8 100644
--- a/arch/arm/include/asm/prom.h
+++ b/arch/arm/include/asm/prom.h
@@ -21,5 +21,16 @@ static inline void irq_dispose_mapping(unsigned int virq)
 	return;
 }
 
+extern void arm_unflatten_device_tree(void);
+extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys);
+
+#else /* CONFIG_OF */
+
+static void arm_unflatten_device_tree(void) { }
+static inline struct machine_desc *setup_machine_fdt(unsigned int dt_phys)
+{
+	return NULL;
+}
+
 #endif /* CONFIG_OF */
 #endif /* ASMARM_PROM_H */
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index 06c4d0e..1cec82a 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -222,6 +222,7 @@ extern struct meminfo meminfo;
 #define bank_phys_size(bank)	(bank)->size
 
 extern int arm_add_memory(unsigned long start, unsigned long size);
+extern char cmd_line[COMMAND_LINE_SIZE];
 
 #endif  /*  __KERNEL__  */
 
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
index ac48da2..07b75bb 100644
--- a/arch/arm/kernel/devtree.c
+++ b/arch/arm/kernel/devtree.c
@@ -21,6 +21,7 @@
 
 #include <asm/setup.h>
 #include <asm/page.h>
+#include <asm/mach/arch.h>
 
 void __init early_init_dt_add_memory_arch(u64 base, u64 size)
 {
@@ -45,3 +46,89 @@ unsigned int irq_create_of_mapping(struct device_node *controller,
 	return intspec[0];
 }
 EXPORT_SYMBOL_GPL(irq_create_of_mapping);
+
+extern struct machine_desc __arch_info_begin, __arch_info_end;
+
+/**
+ * arm_unflatten_device_tree - Copy dtb into a safe area and unflatten it.
+ *
+ * Copies the dtb out of initial memory and into an allocated block so that
+ * it doesn't get overwritten by the kernel and then unflatten it into the
+ * live tree representation.
+ */
+void __init arm_unflatten_device_tree(void)
+{
+	struct boot_param_header *devtree;
+	u32 dtb_size;
+
+	if (!initial_boot_params)
+		return;
+
+	/* Save the dtb to an allocated buffer */
+	dtb_size = be32_to_cpu(initial_boot_params->totalsize);
+	devtree = early_init_dt_alloc_memory_arch(dtb_size, SZ_4K);
+	if (!devtree) {
+		printk("Unable to allocate memory for device tree\n");
+		while(1);
+	}
+	pr_info("relocating device tree from 0x%p to 0x%p, length 0x%x\n",
+		initial_boot_params, devtree, dtb_size);
+	memmove(devtree, initial_boot_params, dtb_size);
+	initial_boot_params = devtree;
+
+	unflatten_device_tree();
+}
+
+/**
+ * setup_machine_fdt - Machine setup when an dtb was passed to the kernel
+ * @dt_phys: physical address of dt blob
+ *
+ * If a dtb was passed to the kernel in r2, then use it to choose the
+ * correct machine_desc and to setup the system.
+ */
+struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
+{
+	struct boot_param_header *devtree = phys_to_virt(dt_phys);
+	struct machine_desc *mdesc, *mdesc_best = NULL;
+	unsigned int score, mdesc_score = ~1;
+	unsigned long dt_root;
+	const char *model;
+
+	/* check device tree validity */
+	if (!dt_phys || be32_to_cpu(devtree->magic) != OF_DT_HEADER)
+		return NULL;
+
+	/* Search the mdescs for the 'best' compatible value match */
+	initial_boot_params = devtree;
+
+	dt_root = of_get_flat_dt_root();
+	for (mdesc = &__arch_info_begin; mdesc < &__arch_info_end; mdesc++) {
+		score = of_flat_dt_match(dt_root, mdesc->dt_compat);
+		if (score > 0 && score < mdesc_score) {
+			mdesc_best = mdesc;
+			mdesc_score = score;
+		}
+	}
+	if (!mdesc_best) {
+		printk("Machine not supported, unable to continue.\n");
+		while (1);
+	}
+
+	model = of_get_flat_dt_prop(dt_root, "model", NULL);
+	if (!model)
+		model = of_get_flat_dt_prop(dt_root, "compatible", NULL);
+	if (!model)
+		model = "<unknown>";
+	pr_info("Machine: %s, model: %s\n", mdesc_best->name, model);
+
+	/* Retrieve various information from the /chosen node */
+	of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
+	/* Initialize {size,address}-cells info */
+	of_scan_flat_dt(early_init_dt_scan_root, NULL);
+	/* Setup memory, calling early_init_dt_add_memory_arch */
+	of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+	/* Save command line for /proc/cmdline  */
+	strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
+
+	return mdesc_best;
+}
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index cbc1836..68e0204 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -20,6 +20,7 @@
 #include <linux/screen_info.h>
 #include <linux/init.h>
 #include <linux/kexec.h>
+#include <linux/of_fdt.h>
 #include <linux/crash_dump.h>
 #include <linux/root_dev.h>
 #include <linux/cpu.h>
@@ -42,6 +43,7 @@
 #include <asm/cachetype.h>
 #include <asm/tlbflush.h>
 
+#include <asm/prom.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
@@ -125,7 +127,7 @@ EXPORT_SYMBOL(elf_platform);
 
 static const char *cpu_name;
 static const char *machine_name;
-static char __initdata cmd_line[COMMAND_LINE_SIZE];
+char cmd_line[COMMAND_LINE_SIZE];
 struct machine_desc *machine_desc __initdata;
 
 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
@@ -838,7 +840,9 @@ void __init setup_arch(char **cmdline_p)
 	unwind_init();
 
 	setup_processor();
-	mdesc = setup_machine_tags(machine_arch_type);
+	mdesc = setup_machine_fdt(__atags_pointer);
+	if (!mdesc)
+		mdesc = setup_machine_tags(machine_arch_type);
 	machine_desc = mdesc;
 	machine_name = mdesc->name;
 
@@ -859,6 +863,8 @@ void __init setup_arch(char **cmdline_p)
 	paging_init(mdesc);
 	request_standard_resources(mdesc);
 
+	arm_unflatten_device_tree();
+
 #ifdef CONFIG_SMP
 	if (is_smp())
 		smp_init_cpus();
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 5164069..62ff2e8 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -71,6 +71,14 @@ static int __init parse_tag_initrd2(const struct tag *tag)
 
 __tagtable(ATAG_INITRD2, parse_tag_initrd2);
 
+#ifdef CONFIG_OF_FLATTREE
+void __init early_init_dt_setup_initrd_arch(unsigned long start, unsigned long end)
+{
+	phys_initrd_start = start;
+	phys_initrd_size = end - start + 1;
+}
+#endif /* CONFIG_OF_FLATTREE */
+
 /*
  * This keeps memory configuration data used by a couple memory
  * initialization functions, as well as show_mem() for the skipping


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 5/6] arm/dt: Basic versatile devicetree support
  2011-01-31 21:03 [PATCH v2 0/6] Basic ARM device support Grant Likely
                   ` (3 preceding siblings ...)
  2011-01-31 21:04 ` [PATCH v2 4/6] arm/dt: probe for platforms via the device tree Grant Likely
@ 2011-01-31 21:04 ` Grant Likely
  2011-01-31 21:04 ` [PATCH v2 6/6] arm/dt: Basic tegra " Grant Likely
  5 siblings, 0 replies; 9+ messages in thread
From: Grant Likely @ 2011-01-31 21:04 UTC (permalink / raw)
  To: nicolas.pitre, Russell King, Catalin Marinas, devicetree-discuss,
	linux-kernel, buytenh, Olof Johansson, john.linn,
	linux-arm-kernel

This patch adds adds very basic support for booting versatile with a
device tree.  It simply allows the existing machine_descs to match
against the versatile ab & pb compatible values so that the kernel can
boot.  Kernel parameters and the initrd pointer is read out of the
tree instead of atags.

This is not complete device tree support.  This change will be
reverted when a new machine_desc is added that can populate the
versatile device registrations directly from data in the tree instead
of using hard coded data.  That change will be made in a future patch.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
 arch/arm/mach-versatile/versatile_ab.c |    6 ++++++
 arch/arm/mach-versatile/versatile_pb.c |    6 ++++++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c
index aa9730f..62053df 100644
--- a/arch/arm/mach-versatile/versatile_ab.c
+++ b/arch/arm/mach-versatile/versatile_ab.c
@@ -33,6 +33,11 @@
 
 #include "core.h"
 
+static const char *versatile_ab_match[] __initdata = {
+	"arm,versatile-ab",
+	NULL,
+};
+
 MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")
 	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
 	.boot_params	= 0x00000100,
@@ -40,4 +45,5 @@ MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")
 	.init_irq	= versatile_init_irq,
 	.timer		= &versatile_timer,
 	.init_machine	= versatile_init,
+	.dt_compat	= versatile_ab_match,
 MACHINE_END
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c
index bf46964..eba12fa 100644
--- a/arch/arm/mach-versatile/versatile_pb.c
+++ b/arch/arm/mach-versatile/versatile_pb.c
@@ -106,6 +106,11 @@ static void __init versatile_pb_init(void)
 	}
 }
 
+static const char *versatile_pb_match[] __initdata = {
+	"arm,versatile-pb",
+	NULL,
+};
+
 MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
 	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
 	.boot_params	= 0x00000100,
@@ -113,4 +118,5 @@ MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
 	.init_irq	= versatile_init_irq,
 	.timer		= &versatile_timer,
 	.init_machine	= versatile_pb_init,
+	.dt_compat	= versatile_pb_match,
 MACHINE_END


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 6/6] arm/dt: Basic tegra devicetree support
  2011-01-31 21:03 [PATCH v2 0/6] Basic ARM device support Grant Likely
                   ` (4 preceding siblings ...)
  2011-01-31 21:04 ` [PATCH v2 5/6] arm/dt: Basic versatile devicetree support Grant Likely
@ 2011-01-31 21:04 ` Grant Likely
  5 siblings, 0 replies; 9+ messages in thread
From: Grant Likely @ 2011-01-31 21:04 UTC (permalink / raw)
  To: nicolas.pitre, Russell King, Catalin Marinas, devicetree-discuss,
	linux-kernel, buytenh, Olof Johansson, john.linn,
	linux-arm-kernel

This patch adds adds very basic support for booting tegra with a
device tree.  It simply allows the existing machine_descs to match
against the tegra compatible values so that the kernel can boot.
Kernel parameters and the initrd pointer is read out of the tree
instead of atags.

This is not complete device tree support.  This change will be
reverted when a new machine_desc is added that can populate the
device registrations directly from data in the tree instead of using
hard coded data.  That change will be made in a future patch.

v2: Fixed cut-and-paste error in commit text

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
 arch/arm/mach-tegra/board-harmony.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index b9dbdb1..99884e9 100644
--- a/arch/arm/mach-tegra/board-harmony.c
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -113,6 +113,11 @@ static void __init tegra_harmony_init(void)
 	platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices));
 }
 
+static const char * tegra_harmony_board_compat[] = {
+	"nvidia,harmony",
+	NULL
+};
+
 MACHINE_START(HARMONY, "harmony")
 	.boot_params  = 0x00000100,
 	.fixup		= tegra_harmony_fixup,
@@ -120,4 +125,5 @@ MACHINE_START(HARMONY, "harmony")
 	.init_machine   = tegra_harmony_init,
 	.map_io         = tegra_map_common_io,
 	.timer          = &tegra_timer,
+	.dt_compat      = tegra_harmony_board_compat,
 MACHINE_END


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 4/6] arm/dt: probe for platforms via the device tree
  2011-01-31 21:04 ` [PATCH v2 4/6] arm/dt: probe for platforms via the device tree Grant Likely
@ 2011-01-31 22:27   ` Nicolas Pitre
  2011-01-31 23:03     ` Grant Likely
  0 siblings, 1 reply; 9+ messages in thread
From: Nicolas Pitre @ 2011-01-31 22:27 UTC (permalink / raw)
  To: Grant Likely
  Cc: Russell King, Catalin Marinas, devicetree-discuss, lkml,
	Lennert Buytenhek, Olof Johansson, john.linn, linux-arm-kernel

On Mon, 31 Jan 2011, Grant Likely wrote:

> If a dtb is passed to the kernel then the kernel needs to iterate
> through compiled-in mdescs looking for one that matches and move the
> dtb data to a safe location before it gets accidentally overwritten by
> the kernel.
> 
> This patch creates a new function, setup_machine_fdt() which is
> analogous to the setup_machine_atags() created in the previous patch.
> It does all the early setup needed to use a device tree machine
> description.  It also creates arm_unflatten_device_tree() which copies
> the dtb into an allocated buffer and unflattens it into the live-tree
> representation.
> 
> v2: Changed to save the dtb by copying into an allocated buffer.
>     - Since the dtb will very likely be passed in the first 16k of ram
>       where the interrupt vectors live, memblock_reserve() is
>       insufficient to protect the dtb data.

This is wrong.  The vector page can be allocated anywhere.  It is 
currently allocated with memblock_alloc(), so if you memblock_reserve() 
the dtb soon enough then it should be safe and the vector page or 
whatever will be allocated somewhere else.

What was the actual problem?


Nicolas

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 4/6] arm/dt: probe for platforms via the device tree
  2011-01-31 22:27   ` Nicolas Pitre
@ 2011-01-31 23:03     ` Grant Likely
  0 siblings, 0 replies; 9+ messages in thread
From: Grant Likely @ 2011-01-31 23:03 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Russell King, Catalin Marinas, devicetree-discuss, lkml,
	Lennert Buytenhek, Olof Johansson, john.linn, linux-arm-kernel

On Mon, Jan 31, 2011 at 3:27 PM, Nicolas Pitre <nicolas.pitre@linaro.org> wrote:
> On Mon, 31 Jan 2011, Grant Likely wrote:
>
>> If a dtb is passed to the kernel then the kernel needs to iterate
>> through compiled-in mdescs looking for one that matches and move the
>> dtb data to a safe location before it gets accidentally overwritten by
>> the kernel.
>>
>> This patch creates a new function, setup_machine_fdt() which is
>> analogous to the setup_machine_atags() created in the previous patch.
>> It does all the early setup needed to use a device tree machine
>> description.  It also creates arm_unflatten_device_tree() which copies
>> the dtb into an allocated buffer and unflattens it into the live-tree
>> representation.
>>
>> v2: Changed to save the dtb by copying into an allocated buffer.
>>     - Since the dtb will very likely be passed in the first 16k of ram
>>       where the interrupt vectors live, memblock_reserve() is
>>       insufficient to protect the dtb data.
>
> This is wrong.  The vector page can be allocated anywhere.  It is
> currently allocated with memblock_alloc(), so if you memblock_reserve()
> the dtb soon enough then it should be safe and the vector page or
> whatever will be allocated somewhere else.

Ah, thanks.  Did not know that.

> What was the actual problem?

I was seeing the first page in memory getting zeroed partway through
the boot process which wiped out the dtb.  I haven't yet narrowed down
to the exact point that it gets overwritten.  It is late enough that
all the early setup dt code works, but before init_machine gets
called.

I'm also seeing a problem with /proc/device-tree getting corrupted on
qemu which I cannot reproduce on Tegra hardware.  Still investigating
this one.

g.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2011-01-31 23:03 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-31 21:03 [PATCH v2 0/6] Basic ARM device support Grant Likely
2011-01-31 21:03 ` [PATCH v2 1/6] arm/dt: Make __vet_atags also accept a dtb image Grant Likely
2011-01-31 21:04 ` [PATCH v2 2/6] arm/dt: Allow CONFIG_OF on ARM Grant Likely
2011-01-31 21:04 ` [PATCH v2 3/6] arm/dt: consolidate atags setup into setup_machine_atags Grant Likely
2011-01-31 21:04 ` [PATCH v2 4/6] arm/dt: probe for platforms via the device tree Grant Likely
2011-01-31 22:27   ` Nicolas Pitre
2011-01-31 23:03     ` Grant Likely
2011-01-31 21:04 ` [PATCH v2 5/6] arm/dt: Basic versatile devicetree support Grant Likely
2011-01-31 21:04 ` [PATCH v2 6/6] arm/dt: Basic tegra " Grant Likely

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).