[U-Boot] [RFC PATCH 0/3] Add device tree support for ARM to U-Boot

These patches add device tree support to the bootm command in u-boot for the ARM. I'm sending the patches to this list first for comments before sending it to the wider audience on the u-boot list.
The only testing so far has shown that this patch does not break non-dt booting. I don't have a dt enabled beagle kernel so I have not tried that yet.
John Rigby (3): FDT: Add fixup support of multiple banks of memory ARM: WIP: add flat device tree support ARM: add config for beagle with fdt enabled
MAKEALL | 1 + arch/arm/include/asm/config.h | 1 + arch/arm/lib/bootm.c | 128 ++++++++++++++- boards.cfg | 1 + common/cmd_bootm.c | 5 +- common/fdt_support.c | 86 +++++----- common/image.c | 7 +- include/configs/omap3_beagle_dt.h | 344 +++++++++++++++++++++++++++++++++++++ include/fdt_support.h | 1 + include/image.h | 2 +- 10 files changed, 531 insertions(+), 45 deletions(-) create mode 100644 include/configs/omap3_beagle_dt.h

Add fdt_fixup_memory_banks and reimplement fdt_fixup_memory to use it.
Signed-off-by: John Rigby john.rigby@linaro.org --- common/fdt_support.c | 86 ++++++++++++++++++++++++++----------------------- include/fdt_support.h | 1 + 2 files changed, 47 insertions(+), 40 deletions(-)
diff --git a/common/fdt_support.c b/common/fdt_support.c index 166f5e1..dc5f040 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -362,10 +362,40 @@ void do_fixup_by_compat_u32(void *fdt, const char *compat, do_fixup_by_compat(fdt, compat, prop, &val, 4, create); }
-int fdt_fixup_memory(void *blob, u64 start, u64 size) +/* + * Get cells len in bytes + * if #NNNN-cells property is 2 then len is 8 + * otherwise len is 4 + */ +static int get_cells_len(void *blob, char *nr_cells_name) +{ + const u32 *cell; + + cell = fdt_getprop(blob, 0, nr_cells_name, NULL); + if (cell && *cell == 2) + return 8; + + return 4; +} + +/* + * Write a 4 or 8 byte big endian cell + */ +static void write_cell(u8 *addr, u64 val, int size) { - int err, nodeoffset, len = 0; - u8 tmp[16]; + int shift = (size - 1) * 8; + while (size-- > 0) { + *addr++ = (val >> shift) & 0xff; + shift -= 8; + } +} + +int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks) +{ + int err, nodeoffset; + int addr_cell_len, size_cell_len, len; + u8 tmp[banks * 8]; + int bank; const u32 *addrcell, *sizecell;
err = fdt_check_header(blob); @@ -391,44 +421,15 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size) return err; }
- addrcell = fdt_getprop(blob, 0, "#address-cells", NULL); - /* use shifts and mask to ensure endianness */ - if ((addrcell) && (*addrcell == 2)) { - tmp[0] = (start >> 56) & 0xff; - tmp[1] = (start >> 48) & 0xff; - tmp[2] = (start >> 40) & 0xff; - tmp[3] = (start >> 32) & 0xff; - tmp[4] = (start >> 24) & 0xff; - tmp[5] = (start >> 16) & 0xff; - tmp[6] = (start >> 8) & 0xff; - tmp[7] = (start ) & 0xff; - len = 8; - } else { - tmp[0] = (start >> 24) & 0xff; - tmp[1] = (start >> 16) & 0xff; - tmp[2] = (start >> 8) & 0xff; - tmp[3] = (start ) & 0xff; - len = 4; - } + addr_cell_len = get_cells_len(blob, "#address-cells"); + size_cell_len = get_cells_len(blob, "#size-cells");
- sizecell = fdt_getprop(blob, 0, "#size-cells", NULL); - /* use shifts and mask to ensure endianness */ - if ((sizecell) && (*sizecell == 2)) { - tmp[0+len] = (size >> 56) & 0xff; - tmp[1+len] = (size >> 48) & 0xff; - tmp[2+len] = (size >> 40) & 0xff; - tmp[3+len] = (size >> 32) & 0xff; - tmp[4+len] = (size >> 24) & 0xff; - tmp[5+len] = (size >> 16) & 0xff; - tmp[6+len] = (size >> 8) & 0xff; - tmp[7+len] = (size ) & 0xff; - len += 8; - } else { - tmp[0+len] = (size >> 24) & 0xff; - tmp[1+len] = (size >> 16) & 0xff; - tmp[2+len] = (size >> 8) & 0xff; - tmp[3+len] = (size ) & 0xff; - len += 4; + for (bank = 0, len = 0; bank < banks; bank++) { + write_cell(tmp + len, start, addr_cell_len); + len += addr_cell_len; + + write_cell(tmp + len, start, size_cell_len); + len += size_cell_len; }
err = fdt_setprop(blob, nodeoffset, "reg", tmp, len); @@ -440,6 +441,11 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size) return 0; }
+int fdt_fixup_memory(void *blob, u64 start, u64 size) +{ + return fdt_fixup_memory_banks(blob, &start, &size, 1); +} + void fdt_fixup_ethernet(void *fdt) { int node, i, j; diff --git a/include/fdt_support.h b/include/fdt_support.h index 871ef45..5f631ea 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -48,6 +48,7 @@ void do_fixup_by_compat(void *fdt, const char *compat, void do_fixup_by_compat_u32(void *fdt, const char *compat, const char *prop, u32 val, int create); int fdt_fixup_memory(void *blob, u64 start, u64 size); +int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks); void fdt_fixup_ethernet(void *fdt); int fdt_find_and_setprop(void *fdt, const char *node, const char *prop, const void *val, int len, int create);

On Aug 5, 2010, at 5:14 PM, John Rigby wrote:
Add fdt_fixup_memory_banks and reimplement fdt_fixup_memory to use it.
Signed-off-by: John Rigby john.rigby@linaro.org
common/fdt_support.c | 86 ++++++++++++++++++++++++++----------------------- include/fdt_support.h | 1 + 2 files changed, 47 insertions(+), 40 deletions(-)
John,
Do you have any sense of how far you intend to go w/device tree's on ARM?
I ask because I've been thinking we actually need to have "live tree" structure representation in u-boot (much like the kernel) to allow us to do some of the manipulations we are doing more and more of.
The problem w/libfdt is that use of 'offsets' to get to nodes can be problematic if the offset changes while manipulating it. There are ways around thus but a number of functions we do would benefit from a more live tree.
Wondering how far you envision ARM going w/device tree and u-boot doing node creations and fix ups.
- k

Kumar,
Right now I'm only looking a basic support. I know there are those who believe that u-boot actually does more manipulation than it should. I'll let Grant speak up if he wants to:).
John
On Thu, Aug 5, 2010 at 5:26 PM, Kumar Gala galak@kernel.crashing.org wrote:
On Aug 5, 2010, at 5:14 PM, John Rigby wrote:
Add fdt_fixup_memory_banks and reimplement fdt_fixup_memory to use it.
Signed-off-by: John Rigby john.rigby@linaro.org
common/fdt_support.c | 86 ++++++++++++++++++++++++++----------------------- include/fdt_support.h | 1 + 2 files changed, 47 insertions(+), 40 deletions(-)
John,
Do you have any sense of how far you intend to go w/device tree's on ARM?
I ask because I've been thinking we actually need to have "live tree" structure representation in u-boot (much like the kernel) to allow us to do some of the manipulations we are doing more and more of.
The problem w/libfdt is that use of 'offsets' to get to nodes can be problematic if the offset changes while manipulating it. There are ways around thus but a number of functions we do would benefit from a more live tree.
Wondering how far you envision ARM going w/device tree and u-boot doing node creations and fix ups.
- k
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On Thu, Aug 5, 2010 at 5:36 PM, John Rigby jcrigby@gmail.com wrote:
On Thu, Aug 5, 2010 at 5:26 PM, Kumar Gala galak@kernel.crashing.org wrote:
On Aug 5, 2010, at 5:14 PM, John Rigby wrote:
Add fdt_fixup_memory_banks and reimplement fdt_fixup_memory to use it.
Signed-off-by: John Rigby john.rigby@linaro.org
common/fdt_support.c | 86 ++++++++++++++++++++++++++----------------------- include/fdt_support.h | 1 + 2 files changed, 47 insertions(+), 40 deletions(-)
John,
Do you have any sense of how far you intend to go w/device tree's on ARM?
I ask because I've been thinking we actually need to have "live tree" structure representation in u-boot (much like the kernel) to allow us to do some of the manipulations we are doing more and more of.
The problem w/libfdt is that use of 'offsets' to get to nodes can be problematic if the offset changes while manipulating it. There are ways around thus but a number of functions we do would benefit from a more live tree.
This is actually a really good point. Offsets changing under your feet is just asking for bugs. I could see this as being a legitimate justification for having a live tree model in libfdt and the ability to transition between the live and flat representations. I was against this when we chatted on IRC the other day as it sounds like overkill, but this is a legitimate concern. dtc has a live tree representation that could probably be migrated into libfdt.
Wondering how far you envision ARM going w/device tree and u-boot doing node creations and fix ups.
Right now I'm only looking a basic support. I know there are those who believe that u-boot actually does more manipulation than it should. I'll let Grant speak up if he wants to:).
:-)
I still stand on my point that hard coding device tree manipulations is asking for trouble. IMNSHO, firmware should really be restricted to very well defined things in the device tree. I've been thinking about this a lot, and I'm going to write a "Recommended Practice" document for dealing with the .dtb at the firmware level. At the moment, I think firmware should be restricted to only touching the /chosen node, the /memory node, and updating well defined things like mac address, but only when the Ethernet node is dereferenced from an /aliases name instead of full path.
I *might* be able to be convinced that firmware should be allowed to modify other properties, but only if it isn't hard coded into the firmware (ie, by using a boot script or other method that can be changed without upgrading firmware). As we've discovered in the past, it is very easy to get into a situation where firmware must be upgraded to deal with a change in the device tree data. (ie. soc node name cannot be changed from "soc5200" to "soc" on the lite5200 because older versions of U-Boot do a pathname lookup) This risk can be mitigated if there are some well defined rules about what firmware is and is not allowed to modify in the tree.
g.

On Aug 10, 2010, at 12:39 PM, Grant Likely wrote:
..... At the moment, I think firmware should be restricted to only touching the /chosen node, the /memory node,
I don't even want it updating these, except maybe for the processor clock speeds.
I'm trying to use device trees as a mechanism for providing resource allocation information in a partitioned, multi-core system. In this case, I don't want the boot firmware making updates to the device tree.
I understand in many cases it's quite convenient to have the boot firmware update the device tree prior to invoking the OS, but this is one time when it's not appreciated. I'm currently experimenting with two models, one using environment variables and another using some kind of device tree tagging (i.e. don't update value if it's not equal to some unique key). Neither method has proven to be better in all cases.
Thanks.
-- Dan

On Tue, Aug 10, 2010 at 2:17 PM, Dan Malek ppc6dev@digitaldans.com wrote:
On Aug 10, 2010, at 12:39 PM, Grant Likely wrote:
..... At the moment, I think firmware should be restricted to only touching the /chosen node, the /memory node,
I don't even want it updating these, except maybe for the processor clock speeds.
Hi Dan! I'm glad you're reading as you're one of the use-cases I was thinking about. :-)
I'm trying to use device trees as a mechanism for providing resource allocation information in a partitioned, multi-core system. In this case, I don't want the boot firmware making updates to the device tree.
Yes, it is really problematic when boot firmware unconditionally makes device tree changes for this exact reason. However, it is also true that there is certain information that firmware really needs to hand off to the kernel, such as the boot parameters string. Traditionally, the chosen node has been the expected place to put that data, but I gather from your comment that even that causes problems in your use-case. (or is it the /memory node that is the issue?) Can you give a concrete example so I understand the issue? The /memory node update was implemented to match the historical behaviour of u-boot setting the memory size in the board_info structure, but perhaps that shouldn't be unconditional.
I understand in many cases it's quite convenient to have the boot firmware update the device tree prior to invoking the OS, but this is one time when it's not appreciated. I'm currently experimenting with two models, one using environment variables and another using some kind of device tree tagging (i.e. don't update value if it's not equal to some unique key). Neither method has proven to be better in all cases.
Cheers, g.

On Aug 10, 2010, at 1:26 PM, Grant Likely wrote:
Hi Dan! I'm glad you're reading as you're one of the use-cases I was thinking about. :-)
Hi Grant. Yeah, it's me, the "special" case :-)
....... but I gather from your comment that even that causes problems in your use-case.
The /chosen hasn't really caused any trouble.
(or is it the /memory node that is the issue?)
Yep, /memory is the big problem.
.... Can you give a concrete example so I understand the issue? The /memory node update was implemented to match the historical behaviour of u-boot setting the memory size in the board_info structure, but perhaps that shouldn't be unconditional.
I use the /memory to define the start/size of the various partitions, which of course only one starts at the base address and none of them represent the entire memory space. Updating this as we do today is bad, but then I can think of other complex ways it could be useful. :-) Like... specify a percentage in the node property and have the firmware update base/size according to previous device tree requests. But, not today.
A little off topic, but since we tend to discuss device trees here. I think Hollis has discussed our use of an "enabled" property, which has become useful. It's becoming evident that it's valuable to define the entire device tree, but then have a property for the device that specified whether it's enabled for use in a particular partition. Today, we take a device tree, make copies for each partition, and modify "enabled" accordingly. I guess it could be extended to include partition information in the property, and we could then perhaps use a single tree for all partitions. The kernel or device drivers then test this to determine if this instance should be using this device. Anyway, just information I'd thought I'd pass along that is still brewing. I don't know if this has any value to boot firmware, maybe yet another way to control device tree updates.
Thanks.
-- Dan

Kumar, Grant:
On Tue, Aug 10, 2010 at 1:39 PM, Grant Likely grant.likely@secretlab.ca wrote:
On Thu, Aug 5, 2010 at 5:36 PM, John Rigby jcrigby@gmail.com wrote:
On Thu, Aug 5, 2010 at 5:26 PM, Kumar Gala galak@kernel.crashing.org wrote:
....
The problem w/libfdt is that use of 'offsets' to get to nodes can be problematic if the offset changes while manipulating it. There are ways around thus but a number of functions we do would benefit from a more live tree.
This is actually a really good point. Offsets changing under your feet is just asking for bugs. I could see this as being a legitimate justification for having a live tree model in libfdt and the ability to transition between the live and flat representations. I was against this when we chatted on IRC the other day as it sounds like overkill, but this is a legitimate concern. dtc has a live tree representation that could probably be migrated into libfdt.
I don't think I fully understood Kumar's question when he first sent it. Now I want to understand. Are these gotcha's and workaround's with libfdt documented anywhere? If not then I would be willing to write up something. But I'll need some pointers to get me started. In the longer term how much work do you think it would be to make libfdt's internal representation dynamic? I would be willing spend some time on this if the consensus is that it is worth having.
Thanks, John

On Tue, Aug 10, 2010 at 3:03 PM, John Rigby john.rigby@linaro.org wrote:
Kumar, Grant:
On Tue, Aug 10, 2010 at 1:39 PM, Grant Likely grant.likely@secretlab.ca wrote:
On Thu, Aug 5, 2010 at 5:36 PM, John Rigby jcrigby@gmail.com wrote:
On Thu, Aug 5, 2010 at 5:26 PM, Kumar Gala galak@kernel.crashing.org wrote:
....
The problem w/libfdt is that use of 'offsets' to get to nodes can be problematic if the offset changes while manipulating it. There are ways around thus but a number of functions we do would benefit from a more live tree.
This is actually a really good point. Offsets changing under your feet is just asking for bugs. I could see this as being a legitimate justification for having a live tree model in libfdt and the ability to transition between the live and flat representations. I was against this when we chatted on IRC the other day as it sounds like overkill, but this is a legitimate concern. dtc has a live tree representation that could probably be migrated into libfdt.
I don't think I fully understood Kumar's question when he first sent it. Now I want to understand. Are these gotcha's and workaround's with libfdt documented anywhere? If not then I would be willing to write up something. But I'll need some pointers to get me started. In the longer term how much work do you think it would be to make libfdt's internal representation dynamic? I would be willing spend some time on this if the consensus is that it is worth having.
libfdt's implementation is *by design* static so that is can be easily supported in minimal firmwares. The live tree would be an additional model in addition to the flattree routines. Take a look in the dtc repo to see how the the device tree compiler uses it.
g.

On Tue, 10 Aug 2010 13:39:57 -0600 Grant Likely grant.likely@secretlab.ca wrote:
:-)
I still stand on my point that hard coding device tree manipulations is asking for trouble. IMNSHO, firmware should really be restricted to very well defined things in the device tree. I've been thinking about this a lot, and I'm going to write a "Recommended Practice" document for dealing with the .dtb at the firmware level. At the moment, I think firmware should be restricted to only touching the /chosen node, the /memory node, and updating well defined things like mac address, but only when the Ethernet node is dereferenced from an /aliases name instead of full path.
When I try to think of the fundamental difference between the above modifications and others, the main thing that I see is maturity/stability. There's nothing special about these except that we've already gone through the pain, and believe (but can't be certain) we've got it right now. We had problems with the /chosen node (must already exist, can't already exist, etc). We did other things before for MAC addresses (hard-coded paths, "mac-address" versus "local-mac-address", etc). What happens if we need multiple memory nodes? What happens if u-boot's use of aliases contradicts some other use? Are even additional types of clock updates off-limits? What about looking up by compatible and distinguishing by address?
I think a question we need to answer is, what *is* the device tree? Is it just a convenient way for Linux to organize its knowledge about the hardware -- in which case, would we have been better off by having firmware not touch it at all, and instead do something like cuImage with bd_t replaced by something more robust and extensible (but not as complicated as a full device tree)?
Or is the device tree a bundle of information handed to the OS by whatever came before it (be it firmware, a replaceable chunk of code sitting on top of firmware, a hypervisor, static partitioning provided by the system designer, or early Linux code to transform a known type of bad device tree into a good one)? This is what it was in Open Firmware, and is my understanding of what it was meant to be in ePAPR.
I think the latter is far more useful. It involves a greater compatibility challenge, but there are escape hatches short of replacing firmware. It scares me less than trying to maintain a static device tree for every way the p4080 reference board could be configured (and deal with support when people use the wrong one). :-)
I *might* be able to be convinced that firmware should be allowed to modify other properties, but only if it isn't hard coded into the firmware (ie, by using a boot script or other method that can be changed without upgrading firmware). As we've discovered in the past, it is very easy to get into a situation where firmware must be upgraded to deal with a change in the device tree data. (ie. soc node name cannot be changed from "soc5200" to "soc" on the lite5200 because older versions of U-Boot do a pathname lookup) This risk can be mitigated if there are some well defined rules about what firmware is and is not allowed to modify in the tree.
There are other ways to mitigate the risk, such as having a recovery mode that boots a different firmware image.
Even if you are stuck with firmware that wants to do broken device tree updates, there are options: - Use a dts that works with the old firmware, and have a wrapper that fixes up whatever you wanted to change in the final tree after the firmware's done with it. - Have two trees. Give u-boot a dtb it likes, and have glue code suck out important bits to stick into the real dtb. Kind of like cuImage, but with a noncompliant dtb instead of bd_t. - Tell u-boot to not do any updates (I think this is possible if you use the subcommand version of bootm and do each stage manually -- or you could give uboot some dummy dtb that it likes and put the real thing in a dtbImage) and hard code everything in the dts. - Just have the OS retain compatibility with the old binding, if it's not completely unusable.
Making the device tree manipulation code replaceable would be nice. In cases where we want to convey some knowledge from the fixed part of the firmware, it would not be too different from unconditionally doing the two-tree thing, except that the firmware tree would be simpler and not associated with the user-supplied dts (i.e. a "better bd_t"), and the glue code wouldn't be tied to a particular OS.
-Scott

Hi All,
This patch series adds support for the eSPI controller found on the newer range of Freescale SoCs including the 85xx, P1/P2xx (and I believe the P4xx) series.
The reason this is an RFC is that unfortunately the hardware on these chips does not permit indefinite SPI transactions on a given chip select. A chip select is asserted only when a 'transaction length' has been passed to the controller. Once the number of characters specified in the transaction length have been transmitted, the controller decides that the 'frame' has ended and de-asserts the chip select after a defined delay. It is not possible to initiate a second transfer without re-initialising the command register, and hence clearing and re-asserting a chip select signal.
This patch set addresses the issue by defining a read/write function in the spi_flash_internal API. Subsequent patches add the freescale eSPI driver and add support for it in the spansion driver and the P1/P2 board configuration header.
I'm pretty sure that there are better ways of doing this, especially if a driver model with support for driver quirks was implemented for instance. Until then however, I assume having some sort of ability to use the SPI controller on these boards would be better than not being able to do anything at all. If anyone has a better solution please feel free to comment.
Regards,
Can
-- drivers/mtd/spi/spansion.c | 60 ++++++++- drivers/mtd/spi/spi_flash.c | 38 +++++- drivers/mtd/spi/spi_flash_internal.h | 9 ++ drivers/spi/Makefile | 1 + drivers/spi/fsl_espi.c | 251 ++++++++++++++++++++++++++++++++++ include/configs/P1_P2_RDB.h | 18 +++ include/fsl_espi.h | 50 +++++++ 7 files changed, 419 insertions(+), 8 deletions(-) mode change 100644 => 100755 drivers/mtd/spi/spansion.c mode change 100644 => 100755 drivers/mtd/spi/spi_flash.c mode change 100644 => 100755 drivers/mtd/spi/spi_flash_internal.h create mode 100755 drivers/spi/fsl_espi.c create mode 100755 include/fsl_espi.h

Dear Can Aydin,
The reason this is an RFC is that unfortunately the hardware on these chips does not permit indefinite SPI transactions on a given chip select. A chip select is asserted only when a 'transaction length' has been passed to the controller. Once the number of characters specified in the transaction length have been transmitted, the controller decides that the 'frame' has ended and de-asserts the chip select after a defined delay. It is not possible to initiate a second transfer without re-initialising the command register, and hence clearing and re-asserting a chip select signal.
This patch set addresses the issue by defining a read/write function in the spi_flash_internal API. Subsequent patches add the freescale eSPI driver and add support for it in the spansion driver and the P1/P2 board configuration header.
I'm pretty sure that there are better ways of doing this, especially if a driver model with support for driver quirks was implemented for instance. Until then however, I assume having some sort of ability to use the SPI controller on these boards would be better than not being able to do anything at all. If anyone has a better solution please feel free to comment.
Can the Chip Select Pins be used as GPIO? It might be simpler to do that than adding a speciality to common code.
mode change 100644 => 100755 drivers/mtd/spi/spansion.c mode change 100644 => 100755 drivers/mtd/spi/spi_flash.c mode change 100644 => 100755 drivers/mtd/spi/spi_flash_internal.h create mode 100755 drivers/spi/fsl_espi.c create mode 100755 include/fsl_espi.h
Having edited from W****** using Samba? Make sure the file modes are and stay 644!
Without looking at the functionality I saw several coding style issues in the patch series: + if ( cmd_len&& cmd ) + memcpy(buffer, cmd, cmd_len); should be like "if (cmd_len && cmd)"
Similar space issues seem to happen all over your patches, examples:
+ for ( i = 0; i< size; i++)
+ return bus == 0&& cs< ESPI_MAX_CS_NUM;
+#define ESPI_COM_CS(x) ((x)<< 30)
You need to fix that globally...
Best Regards,
Reinhard
PS: you might want to wait and see if that patch in common code to fix a special hardware issue is welcome at all ;)

Dear Reinhard,
On 28/09/2010 9:02 PM, Reinhard Meyer wrote:
Dear Can Aydin,
The reason this is an RFC is that unfortunately the hardware on these chips does not permit indefinite SPI transactions on a given chip select. A chip select is asserted only when a 'transaction length' has been passed to the controller. Once the number of characters specified in the transaction length have been transmitted, the controller decides that the 'frame' has ended and de-asserts the chip select after a defined delay. It is not possible to initiate a second transfer without re-initialising the command register, and hence clearing and re-asserting a chip select signal.
This patch set addresses the issue by defining a read/write function in the spi_flash_internal API. Subsequent patches add the freescale eSPI driver and add support for it in the spansion driver and the P1/P2 board configuration header.
I'm pretty sure that there are better ways of doing this, especially if a driver model with support for driver quirks was implemented for instance. Until then however, I assume having some sort of ability to use the SPI controller on these boards would be better than not being able to do anything at all. If anyone has a better solution please feel free to comment.
Can the Chip Select Pins be used as GPIO? It might be simpler to do that than adding a speciality to common code.
True, a GPIO pin could be re-purposed to serve as chip select, but that would involve a soldering iron and a steady hand as the P1/P2xxRDB boards are reference design boards sold by a lot of third party vendors (including Denx if I'm not mistaken) this would detract from the ability to just plug u-boot in and run with it.
People could also choose to bitbang the SPI on their custom hardware but again I feel that might defeat the purpose and spirit of u-boot. (Then again, I'm new so don't quote me on that).
mode change 100644 => 100755 drivers/mtd/spi/spansion.c mode change 100644 => 100755 drivers/mtd/spi/spi_flash.c mode change 100644 => 100755 drivers/mtd/spi/spi_flash_internal.h create mode 100755 drivers/spi/fsl_espi.c create mode 100755 include/fsl_espi.h
Having edited from W****** using Samba? Make sure the file modes are and stay 644!
Dammit, I was hoping to not let on about that. Yes, I am unfortunately confined to a certain OS due to certain factors. Will fix those.
Without looking at the functionality I saw several coding style issues in the patch series:
- if ( cmd_len&& cmd )
memcpy(buffer, cmd, cmd_len);
should be like "if (cmd_len && cmd)"
Similar space issues seem to happen all over your patches, examples:
for ( i = 0; i< size; i++)
return bus == 0&& cs< ESPI_MAX_CS_NUM;
+#define ESPI_COM_CS(x) ((x)<< 30)
You need to fix that globally...
Again I plead newbie. Will fix also.
Best Regards,
Reinhard
PS: you might want to wait and see if that patch in common code to fix a special hardware issue is welcome at all ;)
Well, even if the common code patch is rejected (and breaking the spi_flash abstraction was definitely not the high point of my day), at least the cmd_spi module will work with these boards if only the driver patch gets in. Even that might help those trying to get their own hw off the ground at least somewhat.

Can the Chip Select Pins be used as GPIO? It might be simpler to do that than adding a speciality to common code.
True, a GPIO pin could be re-purposed to serve as chip select, but that would involve a soldering iron and a steady hand as the P1/P2xxRDB boards are reference design boards sold by a lot of third party vendors (including Denx if I'm not mistaken) this would detract from the ability to just plug u-boot in and run with it.
People could also choose to bitbang the SPI on their custom hardware but again I feel that might defeat the purpose and spirit of u-boot. (Then again, I'm new so don't quote me on that).
Quick followup, I may have misunderstood that question. The SPI pins can only be re-purposed as extra data pins for the SDHC. It's not possible to use them as GPIO.

Dear Can Aydin,
In message 4CA1D63E.3090102@locatacorp.com you wrote:
Can the Chip Select Pins be used as GPIO? It might be simpler to do that than adding a speciality to common code.
True, a GPIO pin could be re-purposed to serve as chip select, but that would involve a soldering iron and a steady hand as the P1/P2xxRDB
That was not the question.
Reinhard asked if the SPI Chip Select Pins could be configured such so that they can be used in GPIO mode instead of special function mode. That would make code way simpler.
People could also choose to bitbang the SPI on their custom hardware but again I feel that might defeat the purpose and spirit of u-boot. (Then again, I'm new so don't quote me on that).
Oops? Where exactly do you see conflicts with "the purpose and spirit" of U-Boot?
Best regards,
Wolfgang Denk

Dear Wolfgang Denk, Can Aydin,
True, a GPIO pin could be re-purposed to serve as chip select, but that would involve a soldering iron and a steady hand as the P1/P2xxRDB
That was not the question.
Reinhard asked if the SPI Chip Select Pins could be configured such so that they can be used in GPIO mode instead of special function mode. That would make code way simpler.
Exactly. Just have this pin work as GPIO, while the rest stays special function. But then, some SoCs can not individually assign pins to special functions but can only do that in groups. Maybe that's the issue here.
And then: currently an "sf write" is not restricted in the length of data written. It would be limited due to the malloc needed for the patch.
Reinhard

On 28/09/2010 11:22 PM, Reinhard Meyer wrote:
Dear Wolfgang Denk, Can Aydin,
True, a GPIO pin could be re-purposed to serve as chip select, but that would involve a soldering iron and a steady hand as the P1/P2xxRDB
That was not the question.
Reinhard asked if the SPI Chip Select Pins could be configured such so that they can be used in GPIO mode instead of special function mode. That would make code way simpler.
Exactly. Just have this pin work as GPIO, while the rest stays special function. But then, some SoCs can not individually assign pins to special functions but can only do that in groups. Maybe that's the issue here.
Yes, I realized that was the actual question after I sent the reply. Unfortunately GPIO is not an option for the SPI pins on these particular SoCs. They can only be used either as SPI or as extra data pins for the SDHC.
And then: currently an "sf write" is not restricted in the length of data written. It would be limited due to the malloc needed for the patch.
Reinhard

Dear Wolfgang,
On 28/09/2010 10:46 PM, Wolfgang Denk wrote:
People could also choose to bitbang the SPI on their custom hardware but again I feel that might defeat the purpose and spirit of u-boot. (Then again, I'm new so don't quote me on that).
Oops? Where exactly do you see conflicts with "the purpose and spirit" of U-Boot?
I was mostly referring to u-boot's aim of being a universal boot loader. As an analogy to the Linux kernel, when attempting to support multiple architectures and platforms, there is often the inevitable case where unfortunate hardware quirks have to be handled by some sort of framework for dealing with special cases in the driver model.
As the SPI pins cannot be driven as GPIO, anyone who wants to use this particular feature will necessarily have to implement their own workarounds in the current u-boot code.
Would a better starting point be to just submit the driver(which works fine standalone with cmd_spi) and leave the discussions regarding spi_flash common code for further debate?
Can

Hi Can,
Are there any differences between your patches and http://lists.denx.de/pipermail/u-boot/2009-March/049093.html ?
Best Regards, Shaohui Xie
-----Original Message----- From: u-boot-bounces@lists.denx.de
[mailto:u-boot-bounces@lists.denx.de]
On Behalf Of Can Aydin Sent: Tuesday, September 28, 2010 5:57 PM To: u-boot@lists.denx.de Subject: [U-Boot] [RFC] [PATCH 0/4] Add support for Freescale's 85xx
and
P1/P2xxx eSPI controller
Hi All,
This patch series adds support for the eSPI controller found on the
newer
range of Freescale SoCs including the 85xx, P1/P2xx (and I believe the P4xx) series.
The reason this is an RFC is that unfortunately the hardware on these chips does not permit indefinite SPI transactions on a given chip
select.
A chip select is asserted only when a 'transaction length' has been passed to the controller. Once the number of characters specified in
the
transaction length have been transmitted, the controller decides that
the
'frame' has ended and de-asserts the chip select after a defined
delay.
It is not possible to initiate a second transfer without
re-initialising
the command register, and hence clearing and re-asserting a chip
select
signal.
This patch set addresses the issue by defining a read/write function
in
the spi_flash_internal API. Subsequent patches add the freescale eSPI driver and add support for it in the spansion driver and the P1/P2
board
configuration header.
I'm pretty sure that there are better ways of doing this, especially
if a
driver model with support for driver quirks was implemented for
instance.
Until then however, I assume having some sort of ability to use the
SPI
controller on these boards would be better than not being able to do anything at all. If anyone has a better solution please feel free to comment.
Regards,
Can
-- drivers/mtd/spi/spansion.c | 60 ++++++++- drivers/mtd/spi/spi_flash.c | 38 +++++- drivers/mtd/spi/spi_flash_internal.h | 9 ++ drivers/spi/Makefile | 1 + drivers/spi/fsl_espi.c | 251 ++++++++++++++++++++++++++++++++++ include/configs/P1_P2_RDB.h | 18 +++ include/fsl_espi.h | 50 +++++++ 7 files changed, 419 insertions(+), 8 deletions(-) mode change 100644 => 100755 drivers/mtd/spi/spansion.c mode change 100644 => 100755 drivers/mtd/spi/spi_flash.c mode change 100644 => 100755 drivers/mtd/spi/spi_flash_internal.h create mode 100755 drivers/spi/fsl_espi.c create mode 100755 include/fsl_espi.h
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On 13/10/2010 9:25 PM, Xie Shaohui-B21989 wrote:
Hi Can,
Are there any differences between your patches and http://lists.denx.de/pipermail/u-boot/2009-March/049093.html ?
Best Regards, Shaohui Xie
Hello Shaohui,
Firstly, I apologize for responding so late, we've been having some issues with our mail server.
In terms of differences, the big trivial one is that any modifications to common code such as spi_flash have been removed from the latest iteration of the patch. It is now just an eSPI driver with support added for cmd_spi in P1_P2_RDB.h.
You'll note that the more significant change is that the spi_xfer function works quite differently now; the older version called an 80us delay between the tx and rx buffer accesses and always assumed that the rx buffer had valid data, this caused problems when transferring large amounts data at higher clock rates as tx/rx over-/under-flows would cause data corruption.
Hence, additional macros have also been defined for the various register fields that need to be checked for tx/rx buffer states during the read/write cycle.
Smaller, more cosmetic changes have also been made to reduce magic numbers and such.
I've been trying to send in the v3 submission of the patch for a couple of days now but have not, as yet, succeeded in getting it through. Third time lucky I hope.
Regards,
Can

Add device tree support for ARM. Based on other existing implementations.
Signed-off-by: John Rigby john.rigby@linaro.org --- arch/arm/include/asm/config.h | 1 + arch/arm/lib/bootm.c | 128 ++++++++++++++++++++++++++++++++++++++++- common/cmd_bootm.c | 5 +- common/image.c | 7 ++- include/image.h | 2 +- 5 files changed, 138 insertions(+), 5 deletions(-)
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index b76fd8e..9bca5bc 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -23,5 +23,6 @@
/* Relocation to SDRAM works on all ARM boards */ #define CONFIG_RELOC_FIXUP_WORKS +#define CONFIG_LMB
#endif diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 3101321..e45d974 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -27,6 +27,12 @@ #include <u-boot/zlib.h> #include <asm/byteorder.h>
+#if defined(CONFIG_OF_LIBFDT) +#include <fdt.h> +#include <libfdt.h> +#include <fdt_support.h> +#endif + DECLARE_GLOBAL_DATA_PTR;
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ @@ -50,7 +56,34 @@ static void setup_end_tag (bd_t *bd); static struct tag *params; #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
-int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images) +static ulong get_sp(void); +#if defined(CONFIG_OF_LIBFDT) +static int bootm_linux_fdt(bootm_headers_t *images); +#endif + +void arch_lmb_reserve(struct lmb *lmb) +{ + ulong sp; + + /* + * Booting a (Linux) kernel image + * + * Allocate space for command line and board info - the + * address should be as high as possible within the reach of + * the kernel (see CONFIG_SYS_BOOTMAPSZ settings), but in unused + * memory, which means far enough below the current stack + * pointer. + */ + sp = get_sp(); + debug("## Current stack ends at 0x%08lx ", sp); + + /* adjust sp by 1K to be safe */ + sp -= 1024; + lmb_reserve(lmb, sp, + gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp); +} + +int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) { bd_t *bd = gd->bd; char *s; @@ -64,6 +97,11 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) return 1;
+#ifdef CONFIG_OF_LIBFDT + if (images->ft_len) + return bootm_linux_fdt(images); +#endif + theKernel = (void (*)(int, int, uint))images->ep;
s = getenv ("machid"); @@ -99,7 +137,7 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima if (images->rd_start && images->rd_end) setup_initrd_tag (bd, images->rd_start, images->rd_end); #endif - setup_end_tag (bd); + setup_end_tag(bd); #endif
/* we assume that the kernel is in place */ @@ -120,6 +158,84 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima return 1; }
+#if defined(CONFIG_OF_LIBFDT) +static int fixup_memory_node(void *blob) +{ + bd_t *bd = gd->bd; + int bank; + u64 start[CONFIG_NR_DRAM_BANKS]; + u64 size[CONFIG_NR_DRAM_BANKS]; + + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { + start[bank] = bd->bi_dram[bank].start; + size[bank] = bd->bi_dram[bank].size; + } + + return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); +} + +static int bootm_linux_fdt(bootm_headers_t *images) +{ + ulong rd_len; + bd_t *bd = gd->bd; + char *s; + int machid = bd->bi_arch_number; + void (*theKernel)(int zero, int dt_machid, void *dtblob); + ulong bootmap_base = getenv_bootm_low(); + ulong of_size = images->ft_len; + char **of_flat_tree = &images->ft_addr; + ulong *initrd_start = &images->initrd_start; + ulong *initrd_end = &images->initrd_end; + struct lmb *lmb = &images->lmb; + int ret; + + theKernel = (void (*)(int, int, void *))images->ep; + + s = getenv("machid"); + if (s) { + machid = simple_strtoul(s, NULL, 16); + printf("Using machid 0x%x from environment\n", machid); + } + + show_boot_progress(15); + + rd_len = images->rd_end - images->rd_start; + ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, + initrd_start, initrd_end); + if (ret) + return ret; + + ret = boot_relocate_fdt(lmb, bootmap_base, of_flat_tree, &of_size); + if (ret) + return ret; + + debug("## Transferring control to Linux (at address %08lx) ...\n", + (ulong) theKernel); + + fdt_chosen(*of_flat_tree, 1); + + fixup_memory_node(*of_flat_tree); + + fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1); + + /* we assume that the kernel is in place */ + printf("\nStarting kernel ...\n\n"); + +#ifdef CONFIG_USB_DEVICE + { + extern void udc_disconnect(void); + udc_disconnect(); + } +#endif + + cleanup_before_linux(); + + theKernel(0, machid, *of_flat_tree); + /* does not return */ + + return 1; +} +#endif
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ @@ -239,4 +355,12 @@ static void setup_end_tag (bd_t *bd) params->hdr.size = 0; }
+static ulong get_sp(void) +{ + ulong ret; + + asm("mov %0, sp" : "=r"(ret) : ); + return ret; +} + #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 594bccb..c6207cf 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -301,7 +301,10 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] }
#if defined(CONFIG_OF_LIBFDT) -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#if defined(CONFIG_PPC) || \ + defined(CONFIG_M68K) || \ + defined(CONFIG_SPARC) || \ + defined(CONFIG_ARM) /* find flattened device tree */ ret = boot_get_fdt (flag, argc, argv, &images, &images.ft_addr, &images.ft_len); diff --git a/common/image.c b/common/image.c index 6d8833e..6da38aa 100644 --- a/common/image.c +++ b/common/image.c @@ -985,7 +985,10 @@ int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images, return 0; }
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#if defined(CONFIG_PPC) || \ + defined(CONFIG_M68K) || \ + defined(CONFIG_SPARC) || \ + defined(CONFIG_ARM) /** * boot_ramdisk_high - relocate init ramdisk * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1206,9 +1209,11 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, if (fdt_blob < (char *)bootmap_base) relocate = 1;
+#ifdef CONFIG_SYS_BOOTMAPSZ if ((fdt_blob + *of_size + CONFIG_SYS_FDT_PAD) >= ((char *)CONFIG_SYS_BOOTMAPSZ + bootmap_base)) relocate = 1; +#endif
/* move flattend device tree if needed */ if (relocate) { diff --git a/include/image.h b/include/image.h index bcc08d1..8f06cdc 100644 --- a/include/image.h +++ b/include/image.h @@ -339,7 +339,7 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, char **of_flat_tree, ulong *of_size); #endif
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_ARM) int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, ulong *initrd_start, ulong *initrd_end);

Dear John Rigby,
In message 1281046488-25187-3-git-send-email-john.rigby@linaro.org you wrote:
Add device tree support for ARM. Based on other existing implementations. ... +#ifdef CONFIG_USB_DEVICE
- {
extern void udc_disconnect(void);
udc_disconnect();
- }
+#endif
- cleanup_before_linux();
Should the udc_disconnect(); call not be moved into cleanup_before_linux() ?
+#if defined(CONFIG_PPC) || \
- defined(CONFIG_M68K) || \
- defined(CONFIG_SPARC) || \
- defined(CONFIG_ARM)
Please sort such lists.
Best regards,
Wolfgang Denk

Thanks for the quick review. I'll make your suggested fixes and resubmit.
On Thu, Aug 5, 2010 at 4:31 PM, Wolfgang Denk wd@denx.de wrote:
Dear John Rigby,
In message 1281046488-25187-3-git-send-email-john.rigby@linaro.org you wrote:
Add device tree support for ARM. Based on other existing implementations. ... +#ifdef CONFIG_USB_DEVICE
- {
- extern void udc_disconnect(void);
- udc_disconnect();
- }
+#endif
- cleanup_before_linux();
Should the udc_disconnect(); call not be moved into cleanup_before_linux() ?
+#if defined(CONFIG_PPC) || \
- defined(CONFIG_M68K) || \
- defined(CONFIG_SPARC) || \
- defined(CONFIG_ARM)
Please sort such lists.
Best regards,
Wolfgang Denk
-- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de Why is an average signature file longer than an average Perl script??

On Thu, Aug 5, 2010 at 4:14 PM, John Rigby john.rigby@linaro.org wrote:
Add device tree support for ARM. Based on other existing implementations.
Hi John,
minor comments.
Signed-off-by: John Rigby john.rigby@linaro.org
arch/arm/include/asm/config.h | 1 + arch/arm/lib/bootm.c | 128 ++++++++++++++++++++++++++++++++++++++++- common/cmd_bootm.c | 5 +- common/image.c | 7 ++- include/image.h | 2 +- 5 files changed, 138 insertions(+), 5 deletions(-)
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index b76fd8e..9bca5bc 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -23,5 +23,6 @@
/* Relocation to SDRAM works on all ARM boards */ #define CONFIG_RELOC_FIXUP_WORKS +#define CONFIG_LMB
#endif diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 3101321..e45d974 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -27,6 +27,12 @@ #include <u-boot/zlib.h> #include <asm/byteorder.h>
+#if defined(CONFIG_OF_LIBFDT) +#include <fdt.h> +#include <libfdt.h> +#include <fdt_support.h> +#endif
Can these be included unconditionally? Will they hurt anything when CONFIG_OF_LIBFDT is not selected? (and if they do, maybe the headers themselves should be fixed to be safe)
DECLARE_GLOBAL_DATA_PTR;
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ @@ -50,7 +56,34 @@ static void setup_end_tag (bd_t *bd); static struct tag *params; #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
-int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images) +static ulong get_sp(void); +#if defined(CONFIG_OF_LIBFDT) +static int bootm_linux_fdt(bootm_headers_t *images); +#endif
+void arch_lmb_reserve(struct lmb *lmb) +{
- ulong sp;
- /*
- * Booting a (Linux) kernel image
- *
- * Allocate space for command line and board info - the
- * address should be as high as possible within the reach of
- * the kernel (see CONFIG_SYS_BOOTMAPSZ settings), but in unused
- * memory, which means far enough below the current stack
- * pointer.
- */
- sp = get_sp();
- debug("## Current stack ends at 0x%08lx ", sp);
- /* adjust sp by 1K to be safe */
- sp -= 1024;
- lmb_reserve(lmb, sp,
- gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp);
+}
+int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) { bd_t *bd = gd->bd; char *s; @@ -64,6 +97,11 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) return 1;
+#ifdef CONFIG_OF_LIBFDT
- if (images->ft_len)
- return bootm_linux_fdt(images);
+#endif
theKernel = (void (*)(int, int, uint))images->ep;
s = getenv ("machid"); @@ -99,7 +137,7 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima if (images->rd_start && images->rd_end) setup_initrd_tag (bd, images->rd_start, images->rd_end); #endif
- setup_end_tag (bd);
- setup_end_tag(bd);
#endif
/* we assume that the kernel is in place */ @@ -120,6 +158,84 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima return 1; }
+#if defined(CONFIG_OF_LIBFDT) +static int fixup_memory_node(void *blob) +{
- bd_t *bd = gd->bd;
- int bank;
- u64 start[CONFIG_NR_DRAM_BANKS];
- u64 size[CONFIG_NR_DRAM_BANKS];
- for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
- start[bank] = bd->bi_dram[bank].start;
- size[bank] = bd->bi_dram[bank].size;
- }
- return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS);
+}
+static int bootm_linux_fdt(bootm_headers_t *images) +{
- ulong rd_len;
- bd_t *bd = gd->bd;
- char *s;
- int machid = bd->bi_arch_number;
- void (*theKernel)(int zero, int dt_machid, void *dtblob);
- ulong bootmap_base = getenv_bootm_low();
- ulong of_size = images->ft_len;
- char **of_flat_tree = &images->ft_addr;
- ulong *initrd_start = &images->initrd_start;
- ulong *initrd_end = &images->initrd_end;
- struct lmb *lmb = &images->lmb;
- int ret;
- theKernel = (void (*)(int, int, void *))images->ep;
U-Boot naming convention is lowercase with underscores, just like the kernel.
- s = getenv("machid");
- if (s) {
- machid = simple_strtoul(s, NULL, 16);
- printf("Using machid 0x%x from environment\n", machid);
- }
- show_boot_progress(15);
- rd_len = images->rd_end - images->rd_start;
- ret = boot_ramdisk_high(lmb, images->rd_start, rd_len,
- initrd_start, initrd_end);
- if (ret)
- return ret;
- ret = boot_relocate_fdt(lmb, bootmap_base, of_flat_tree, &of_size);
- if (ret)
- return ret;
- debug("## Transferring control to Linux (at address %08lx) ...\n",
- (ulong) theKernel);
- fdt_chosen(*of_flat_tree, 1);
- fixup_memory_node(*of_flat_tree);
- fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1);
- /* we assume that the kernel is in place */
- printf("\nStarting kernel ...\n\n");
+#ifdef CONFIG_USB_DEVICE
- {
- extern void udc_disconnect(void);
- udc_disconnect();
- }
+#endif
- cleanup_before_linux();
- theKernel(0, machid, *of_flat_tree);
- /* does not return */
- return 1;
+} +#endif
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ @@ -239,4 +355,12 @@ static void setup_end_tag (bd_t *bd) params->hdr.size = 0; }
+static ulong get_sp(void) +{
- ulong ret;
- asm("mov %0, sp" : "=r"(ret) : );
- return ret;
+}
#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 594bccb..c6207cf 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -301,7 +301,10 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] }
#if defined(CONFIG_OF_LIBFDT) -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#if defined(CONFIG_PPC) || \
- defined(CONFIG_M68K) || \
- defined(CONFIG_SPARC) || \
- defined(CONFIG_ARM)
There's got to be a better way to do this. :-) Are there other architectures from PPC, M68K and SPARC that have OF_LIBFDT set?
/* find flattened device tree */ ret = boot_get_fdt (flag, argc, argv, &images, &images.ft_addr, &images.ft_len); diff --git a/common/image.c b/common/image.c index 6d8833e..6da38aa 100644 --- a/common/image.c +++ b/common/image.c @@ -985,7 +985,10 @@ int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images, return 0; }
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#if defined(CONFIG_PPC) || \
- defined(CONFIG_M68K) || \
- defined(CONFIG_SPARC) || \
- defined(CONFIG_ARM)
/** * boot_ramdisk_high - relocate init ramdisk * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1206,9 +1209,11 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, if (fdt_blob < (char *)bootmap_base) relocate = 1;
+#ifdef CONFIG_SYS_BOOTMAPSZ if ((fdt_blob + *of_size + CONFIG_SYS_FDT_PAD) >= ((char *)CONFIG_SYS_BOOTMAPSZ + bootmap_base)) relocate = 1; +#endif
/* move flattend device tree if needed */ if (relocate) { diff --git a/include/image.h b/include/image.h index bcc08d1..8f06cdc 100644 --- a/include/image.h +++ b/include/image.h @@ -339,7 +339,7 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, char **of_flat_tree, ulong *of_size); #endif
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_ARM) int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, ulong *initrd_start, ulong *initrd_end);
-- 1.7.0.4
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On Tue, Aug 10, 2010 at 1:44 PM, Grant Likely grant.likely@secretlab.ca wrote:
On Thu, Aug 5, 2010 at 4:14 PM, John Rigby john.rigby@linaro.org wrote:
Add device tree support for ARM. Based on other existing implementations.
Hi John,
minor comments.
BTW, is the u-boot fdt support code little-endian safe? libfdt should be, but does the arm support use any code written for ppc that has not been little-endian scrubbed?
g.
Signed-off-by: John Rigby john.rigby@linaro.org
arch/arm/include/asm/config.h | 1 + arch/arm/lib/bootm.c | 128 ++++++++++++++++++++++++++++++++++++++++- common/cmd_bootm.c | 5 +- common/image.c | 7 ++- include/image.h | 2 +- 5 files changed, 138 insertions(+), 5 deletions(-)
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index b76fd8e..9bca5bc 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -23,5 +23,6 @@
/* Relocation to SDRAM works on all ARM boards */ #define CONFIG_RELOC_FIXUP_WORKS +#define CONFIG_LMB
#endif diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 3101321..e45d974 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -27,6 +27,12 @@ #include <u-boot/zlib.h> #include <asm/byteorder.h>
+#if defined(CONFIG_OF_LIBFDT) +#include <fdt.h> +#include <libfdt.h> +#include <fdt_support.h> +#endif
Can these be included unconditionally? Will they hurt anything when CONFIG_OF_LIBFDT is not selected? (and if they do, maybe the headers themselves should be fixed to be safe)
DECLARE_GLOBAL_DATA_PTR;
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ @@ -50,7 +56,34 @@ static void setup_end_tag (bd_t *bd); static struct tag *params; #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
-int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images) +static ulong get_sp(void); +#if defined(CONFIG_OF_LIBFDT) +static int bootm_linux_fdt(bootm_headers_t *images); +#endif
+void arch_lmb_reserve(struct lmb *lmb) +{
- ulong sp;
- /*
- * Booting a (Linux) kernel image
- *
- * Allocate space for command line and board info - the
- * address should be as high as possible within the reach of
- * the kernel (see CONFIG_SYS_BOOTMAPSZ settings), but in unused
- * memory, which means far enough below the current stack
- * pointer.
- */
- sp = get_sp();
- debug("## Current stack ends at 0x%08lx ", sp);
- /* adjust sp by 1K to be safe */
- sp -= 1024;
- lmb_reserve(lmb, sp,
- gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp);
+}
+int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) { bd_t *bd = gd->bd; char *s; @@ -64,6 +97,11 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) return 1;
+#ifdef CONFIG_OF_LIBFDT
- if (images->ft_len)
- return bootm_linux_fdt(images);
+#endif
theKernel = (void (*)(int, int, uint))images->ep;
s = getenv ("machid"); @@ -99,7 +137,7 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima if (images->rd_start && images->rd_end) setup_initrd_tag (bd, images->rd_start, images->rd_end); #endif
- setup_end_tag (bd);
- setup_end_tag(bd);
#endif
/* we assume that the kernel is in place */ @@ -120,6 +158,84 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima return 1; }
+#if defined(CONFIG_OF_LIBFDT) +static int fixup_memory_node(void *blob) +{
- bd_t *bd = gd->bd;
- int bank;
- u64 start[CONFIG_NR_DRAM_BANKS];
- u64 size[CONFIG_NR_DRAM_BANKS];
- for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
- start[bank] = bd->bi_dram[bank].start;
- size[bank] = bd->bi_dram[bank].size;
- }
- return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS);
+}
+static int bootm_linux_fdt(bootm_headers_t *images) +{
- ulong rd_len;
- bd_t *bd = gd->bd;
- char *s;
- int machid = bd->bi_arch_number;
- void (*theKernel)(int zero, int dt_machid, void *dtblob);
- ulong bootmap_base = getenv_bootm_low();
- ulong of_size = images->ft_len;
- char **of_flat_tree = &images->ft_addr;
- ulong *initrd_start = &images->initrd_start;
- ulong *initrd_end = &images->initrd_end;
- struct lmb *lmb = &images->lmb;
- int ret;
- theKernel = (void (*)(int, int, void *))images->ep;
U-Boot naming convention is lowercase with underscores, just like the kernel.
- s = getenv("machid");
- if (s) {
- machid = simple_strtoul(s, NULL, 16);
- printf("Using machid 0x%x from environment\n", machid);
- }
- show_boot_progress(15);
- rd_len = images->rd_end - images->rd_start;
- ret = boot_ramdisk_high(lmb, images->rd_start, rd_len,
- initrd_start, initrd_end);
- if (ret)
- return ret;
- ret = boot_relocate_fdt(lmb, bootmap_base, of_flat_tree, &of_size);
- if (ret)
- return ret;
- debug("## Transferring control to Linux (at address %08lx) ...\n",
- (ulong) theKernel);
- fdt_chosen(*of_flat_tree, 1);
- fixup_memory_node(*of_flat_tree);
- fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1);
- /* we assume that the kernel is in place */
- printf("\nStarting kernel ...\n\n");
+#ifdef CONFIG_USB_DEVICE
- {
- extern void udc_disconnect(void);
- udc_disconnect();
- }
+#endif
- cleanup_before_linux();
- theKernel(0, machid, *of_flat_tree);
- /* does not return */
- return 1;
+} +#endif
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ @@ -239,4 +355,12 @@ static void setup_end_tag (bd_t *bd) params->hdr.size = 0; }
+static ulong get_sp(void) +{
- ulong ret;
- asm("mov %0, sp" : "=r"(ret) : );
- return ret;
+}
#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 594bccb..c6207cf 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -301,7 +301,10 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] }
#if defined(CONFIG_OF_LIBFDT) -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#if defined(CONFIG_PPC) || \
- defined(CONFIG_M68K) || \
- defined(CONFIG_SPARC) || \
- defined(CONFIG_ARM)
There's got to be a better way to do this. :-) Are there other architectures from PPC, M68K and SPARC that have OF_LIBFDT set?
/* find flattened device tree */ ret = boot_get_fdt (flag, argc, argv, &images, &images.ft_addr, &images.ft_len); diff --git a/common/image.c b/common/image.c index 6d8833e..6da38aa 100644 --- a/common/image.c +++ b/common/image.c @@ -985,7 +985,10 @@ int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images, return 0; }
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#if defined(CONFIG_PPC) || \
- defined(CONFIG_M68K) || \
- defined(CONFIG_SPARC) || \
- defined(CONFIG_ARM)
/** * boot_ramdisk_high - relocate init ramdisk * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1206,9 +1209,11 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, if (fdt_blob < (char *)bootmap_base) relocate = 1;
+#ifdef CONFIG_SYS_BOOTMAPSZ if ((fdt_blob + *of_size + CONFIG_SYS_FDT_PAD) >= ((char *)CONFIG_SYS_BOOTMAPSZ + bootmap_base)) relocate = 1; +#endif
/* move flattend device tree if needed */ if (relocate) { diff --git a/include/image.h b/include/image.h index bcc08d1..8f06cdc 100644 --- a/include/image.h +++ b/include/image.h @@ -339,7 +339,7 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, char **of_flat_tree, ulong *of_size); #endif
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_ARM) int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, ulong *initrd_start, ulong *initrd_end);
-- 1.7.0.4
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
-- Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd.

Le 10/08/2010 21:44, Grant Likely a écrit :
#if defined(CONFIG_OF_LIBFDT) -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#if defined(CONFIG_PPC) || \
- defined(CONFIG_M68K) || \
- defined(CONFIG_SPARC) || \
- defined(CONFIG_ARM)
There's got to be a better way to do this. :-)
Reminds me of an issue I encountered in my orion5x ide support patch series where I also had modified a rather complex condition in cmd_ide.c, which determined whether swapping I/O byte reads was needed.
Wolfgang had asked me to replace with a condition on a single new CONFIG_IDE_SWAP_IO macro, which in turn had to be defined in various cpu, SoC or board config files.
The patch is there: http://article.gmane.org/gmane.comp.boot-loaders.u-boot/82109/match=ide
Maybe the same principle could apply here?
Amicalement,

Thanks Albert, this is an excellent idea.
On Tue, Aug 10, 2010 at 2:23 PM, Albert ARIBAUD albert.aribaud@free.fr wrote:
Le 10/08/2010 21:44, Grant Likely a écrit :
#if defined(CONFIG_OF_LIBFDT) -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#if defined(CONFIG_PPC) || \
- defined(CONFIG_M68K) || \
- defined(CONFIG_SPARC) || \
- defined(CONFIG_ARM)
There's got to be a better way to do this. :-)
Reminds me of an issue I encountered in my orion5x ide support patch series where I also had modified a rather complex condition in cmd_ide.c, which determined whether swapping I/O byte reads was needed.
Wolfgang had asked me to replace with a condition on a single new CONFIG_IDE_SWAP_IO macro, which in turn had to be defined in various cpu, SoC or board config files.
The patch is there: http://article.gmane.org/gmane.comp.boot-loaders.u-boot/82109/match=ide
Maybe the same principle could apply here?
Amicalement,
Albert. _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Dear John Rigby,
In message AANLkTin=irnmA_TLCjvvaJ4k-Q_SHQboHP33hj-0bjui@mail.gmail.com you wrote:
Thanks Albert, this is an excellent idea.
On Tue, Aug 10, 2010 at 2:23 PM, Albert ARIBAUD albert.aribaud@free.fr wr=
Full quote delted.
Please DO NOT top post / full quote.
Thanks.
Wolfgang Denk

This is just for testing ARM device tree support. There is no device tree enabled arm kernel at the moment.
Signed-off-by: John Rigby john.rigby@linaro.org --- MAKEALL | 1 + boards.cfg | 1 + include/configs/omap3_beagle_dt.h | 344 +++++++++++++++++++++++++++++++++++++ 3 files changed, 346 insertions(+), 0 deletions(-) create mode 100644 include/configs/omap3_beagle_dt.h
diff --git a/MAKEALL b/MAKEALL index b34ae33..cdecb28 100755 --- a/MAKEALL +++ b/MAKEALL @@ -654,6 +654,7 @@ LIST_ARMV7=" \ devkit8000 \ mx51evk \ omap3_beagle \ + omap3_beagle_dt \ omap3_overo \ omap3_evm \ omap3_pandora \ diff --git a/boards.cfg b/boards.cfg index a70f541..09ba103 100644 --- a/boards.cfg +++ b/boards.cfg @@ -259,6 +259,7 @@ omap3_pandora arm armv7 pandora - omap3 omap3_zoom1 arm armv7 zoom1 logicpd omap3 omap3_zoom2 arm armv7 zoom2 logicpd omap3 omap3_beagle arm armv7 beagle ti omap3 +omap3_beagle_dt arm armv7 beagle ti omap3 omap3_evm arm armv7 evm ti omap3 omap3_sdp3430 arm armv7 sdp3430 ti omap3 omap4_panda arm armv7 panda ti omap4 diff --git a/include/configs/omap3_beagle_dt.h b/include/configs/omap3_beagle_dt.h new file mode 100644 index 0000000..6bd3c7b --- /dev/null +++ b/include/configs/omap3_beagle_dt.h @@ -0,0 +1,344 @@ +/* + * (C) Copyright 2006-2008 + * Texas Instruments. + * Richard Woodruff r-woodruff2@ti.com + * Syed Mohammed Khasim x0khasim@ti.com + * + * Configuration settings for the TI OMAP3530 Beagle board. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + */ +#define CONFIG_ARMV7 1 /* This is an ARM V7 CPU core */ +#define CONFIG_OMAP 1 /* in a TI OMAP core */ +#define CONFIG_OMAP34XX 1 /* which is a 34XX */ +#define CONFIG_OMAP3430 1 /* which is in a 3430 */ +#define CONFIG_OMAP3_BEAGLE 1 /* working with BEAGLE */ + +#define CONFIG_SDRC /* The chip has SDRC controller */ + +#include <asm/arch/cpu.h> /* get chip and board defs */ +#include <asm/arch/omap3.h> + +/* + * Display CPU and Board information + */ +#define CONFIG_DISPLAY_CPUINFO 1 +#define CONFIG_DISPLAY_BOARDINFO 1 + +/* Clock Defines */ +#define V_OSCK 26000000 /* Clock output from T2 */ +#define V_SCLK (V_OSCK >> 1) + +#undef CONFIG_USE_IRQ /* no support for IRQs */ +#define CONFIG_MISC_INIT_R + +#define CONFIG_OF_LIBFDT 1 +#define CONFIG_SYS_BOOTMAPSZ (8 << 20) + +#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ +#define CONFIG_SETUP_MEMORY_TAGS 1 +#define CONFIG_INITRD_TAG 1 +#define CONFIG_REVISION_TAG 1 + +/* + * Size of malloc() pool + */ +#define CONFIG_ENV_SIZE (128 << 10) /* 128 KiB */ + /* Sector */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (128 << 10)) +#define CONFIG_SYS_GBL_DATA_SIZE 128 /* bytes reserved for */ + /* initial data */ + +/* + * Hardware drivers + */ + +/* + * NS16550 Configuration + */ +#define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */ + +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE (-4) +#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK + +/* + * select serial console configuration + */ +#define CONFIG_CONS_INDEX 3 +#define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3 +#define CONFIG_SERIAL3 3 /* UART3 on Beagle Rev 2 */ + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\ + 115200} +#define CONFIG_MMC 1 +#define CONFIG_OMAP3_MMC 1 +#define CONFIG_DOS_PARTITION 1 + +/* DDR - I use Micron DDR */ +#define CONFIG_OMAP3_MICRON_DDR 1 + +/* USB */ +#define CONFIG_MUSB_UDC 1 +#define CONFIG_USB_OMAP3 1 +#define CONFIG_TWL4030_USB 1 + +/* USB device configuration */ +#define CONFIG_USB_DEVICE 1 +#define CONFIG_USB_TTY 1 +#define CONFIG_SYS_CONSOLE_IS_IN_ENV 1 +/* Change these to suit your needs */ +#define CONFIG_USBD_VENDORID 0x0451 +#define CONFIG_USBD_PRODUCTID 0x5678 +#define CONFIG_USBD_MANUFACTURER "Texas Instruments" +#define CONFIG_USBD_PRODUCT_NAME "Beagle" + +/* commands to include */ +#include <config_cmd_default.h> + +#define CONFIG_CMD_EXT2 /* EXT2 Support */ +#define CONFIG_CMD_FAT /* FAT support */ +#define CONFIG_CMD_JFFS2 /* JFFS2 Support */ +#define CONFIG_CMD_MTDPARTS /* Enable MTD parts commands */ +#define CONFIG_MTD_DEVICE /* needed for mtdparts commands */ +#define MTDIDS_DEFAULT "nand0=nand" +#define MTDPARTS_DEFAULT "mtdparts=nand:512k(x-loader),"\ + "1920k(u-boot),128k(u-boot-env),"\ + "4m(kernel),-(fs)" + +#define CONFIG_CMD_I2C /* I2C serial bus support */ +#define CONFIG_CMD_MMC /* MMC support */ +#define CONFIG_CMD_NAND /* NAND support */ + +#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */ +#undef CONFIG_CMD_FPGA /* FPGA configuration Support */ +#undef CONFIG_CMD_IMI /* iminfo */ +#undef CONFIG_CMD_IMLS /* List all found images */ +#undef CONFIG_CMD_NET /* bootp, tftpboot, rarpboot */ +#undef CONFIG_CMD_NFS /* NFS support */ + +#define CONFIG_SYS_NO_FLASH +#define CONFIG_HARD_I2C 1 +#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_SYS_I2C_SLAVE 1 +#define CONFIG_SYS_I2C_BUS 0 +#define CONFIG_SYS_I2C_BUS_SELECT 1 +#define CONFIG_DRIVER_OMAP34XX_I2C 1 +#define CONFIG_I2C_MULTI_BUS 1 + +/* + * TWL4030 + */ +#define CONFIG_TWL4030_POWER 1 +#define CONFIG_TWL4030_LED 1 + +/* + * Board NAND Info. + */ +#define CONFIG_SYS_NAND_QUIET_TEST 1 +#define CONFIG_NAND_OMAP_GPMC +#define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */ + /* to access nand */ +#define CONFIG_SYS_NAND_BASE NAND_BASE /* physical address */ + /* to access nand at */ + /* CS0 */ +#define GPMC_NAND_ECC_LP_x16_LAYOUT 1 + +#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND */ + /* devices */ +#define CONFIG_JFFS2_NAND +/* nand device jffs2 lives on */ +#define CONFIG_JFFS2_DEV "nand0" +/* start of jffs2 partition */ +#define CONFIG_JFFS2_PART_OFFSET 0x680000 +#define CONFIG_JFFS2_PART_SIZE 0xf980000 /* size of jffs2 */ + /* partition */ + +/* Environment information */ +#define CONFIG_BOOTDELAY 10 + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "loadaddr=0x82000000\0" \ + "usbtty=cdc_acm\0" \ + "console=ttyS2,115200n8\0" \ + "mpurate=500\0" \ + "vram=12M\0" \ + "dvimode=1024x768MR-16@60\0" \ + "defaultdisplay=dvi\0" \ + "mmcroot=/dev/mmcblk0p2 rw\0" \ + "mmcrootfstype=ext3 rootwait\0" \ + "nandroot=/dev/mtdblock4 rw\0" \ + "nandrootfstype=jffs2\0" \ + "mmcargs=setenv bootargs console=${console} " \ + "mpurate=${mpurate} " \ + "vram=${vram} " \ + "omapfb.mode=dvi:${dvimode} " \ + "omapdss.def_disp=${defaultdisplay} " \ + "root=${mmcroot} " \ + "rootfstype=${mmcrootfstype}\0" \ + "nandargs=setenv bootargs console=${console} " \ + "mpurate=${mpurate} " \ + "vram=${vram} " \ + "omapfb.mode=dvi:${dvimode} " \ + "omapdss.def_disp=${defaultdisplay} " \ + "root=${nandroot} " \ + "rootfstype=${nandrootfstype}\0" \ + "loadbootscript=fatload mmc 0 ${loadaddr} boot.scr\0" \ + "bootscript=echo Running bootscript from mmc ...; " \ + "source ${loadaddr}\0" \ + "loaduimage=fatload mmc 0 ${loadaddr} uImage\0" \ + "mmcboot=echo Booting from mmc ...; " \ + "run mmcargs; " \ + "bootm ${loadaddr}\0" \ + "nandboot=echo Booting from nand ...; " \ + "run nandargs; " \ + "nand read ${loadaddr} 280000 400000; " \ + "bootm ${loadaddr}\0" \ + +#define CONFIG_BOOTCOMMAND \ + "if mmc init; then " \ + "if run loadbootscript; then " \ + "run bootscript; " \ + "else " \ + "if run loaduimage; then " \ + "run mmcboot; " \ + "else run nandboot; " \ + "fi; " \ + "fi; " \ + "else run nandboot; fi" + +#define CONFIG_AUTO_COMPLETE 1 +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#define CONFIG_SYS_PROMPT "OMAP3 beagleboard.org # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +/* Print Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE) + +#define CONFIG_SYS_MEMTEST_START (OMAP34XX_SDRC_CS0) /* memtest */ + /* works on */ +#define CONFIG_SYS_MEMTEST_END (OMAP34XX_SDRC_CS0 + \ + 0x01F00000) /* 31MB */ + +#define CONFIG_SYS_LOAD_ADDR (OMAP34XX_SDRC_CS0) /* default */ + /* load address */ + +/* + * OMAP3 has 12 GP timers, they can be driven by the system clock + * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK). + * This rate is divided by a local divisor. + */ +#define CONFIG_SYS_TIMERBASE (OMAP34XX_GPT2) +#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */ +#define CONFIG_SYS_HZ 1000 + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128 << 10) /* regular stack 128 KiB */ +#ifdef CONFIG_USE_IRQ +#define CONFIG_STACKSIZE_IRQ (4 << 10) /* IRQ stack 4 KiB */ +#define CONFIG_STACKSIZE_FIQ (4 << 10) /* FIQ stack 4 KiB */ +#endif + +/*----------------------------------------------------------------------- + * Physical Memory Map + */ +#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */ +#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0 +#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 MiB */ +#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1 + +/* SDRAM Bank Allocation method */ +#define SDRC_R_B_C 1 + +/*----------------------------------------------------------------------- + * FLASH and environment organization + */ + +/* **** PISMO SUPPORT *** */ + +/* Configure the PISMO */ +#define PISMO1_NAND_SIZE GPMC_SIZE_128M +#define PISMO1_ONEN_SIZE GPMC_SIZE_128M + +#define CONFIG_SYS_MAX_FLASH_SECT 520 /* max number of sectors on */ + /* one chip */ +#define CONFIG_SYS_MAX_FLASH_BANKS 2 /* max number of flash banks */ +#define CONFIG_SYS_MONITOR_LEN (256 << 10) /* Reserve 2 sectors */ + +#define CONFIG_SYS_FLASH_BASE boot_flash_base + +/* Monitor at start of flash */ +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE +#define CONFIG_SYS_ONENAND_BASE ONENAND_MAP + +#define CONFIG_ENV_IS_IN_NAND 1 +#define ONENAND_ENV_OFFSET 0x260000 /* environment starts here */ +#define SMNAND_ENV_OFFSET 0x260000 /* environment starts here */ + +#define CONFIG_SYS_ENV_SECT_SIZE boot_flash_sec +#define CONFIG_ENV_OFFSET boot_flash_off +#define CONFIG_ENV_ADDR SMNAND_ENV_OFFSET + +/*----------------------------------------------------------------------- + * CFI FLASH driver setup + */ +/* timeout values are in ticks */ +#define CONFIG_SYS_FLASH_ERASE_TOUT (100 * CONFIG_SYS_HZ) +#define CONFIG_SYS_FLASH_WRITE_TOUT (100 * CONFIG_SYS_HZ) + +/* Flash banks JFFS2 should use */ +#define CONFIG_SYS_MAX_MTD_BANKS (CONFIG_SYS_MAX_FLASH_BANKS + \ + CONFIG_SYS_MAX_NAND_DEVICE) +#define CONFIG_SYS_JFFS2_MEM_NAND +/* use flash_info[2] */ +#define CONFIG_SYS_JFFS2_FIRST_BANK CONFIG_SYS_MAX_FLASH_BANKS +#define CONFIG_SYS_JFFS2_NUM_BANKS 1 + +#ifndef __ASSEMBLY__ +extern unsigned int boot_flash_base; +extern volatile unsigned int boot_flash_env_addr; +extern unsigned int boot_flash_off; +extern unsigned int boot_flash_sec; +extern unsigned int boot_flash_type; +#endif + +#endif /* __CONFIG_H */

Dear John Rigby,
In message 1281046488-25187-4-git-send-email-john.rigby@linaro.org you wrote:
This is just for testing ARM device tree support. There is no device tree enabled arm kernel at the moment.
Signed-off-by: John Rigby john.rigby@linaro.org
MAKEALL | 1 + boards.cfg | 1 + include/configs/omap3_beagle_dt.h | 344 +++++++++++++++++++++++++++++++++++++ 3 files changed, 346 insertions(+), 0 deletions(-) create mode 100644 include/configs/omap3_beagle_dt.h
NAK.
Please do not add a separate config file where only 9 out of 344 lines are different from the existing one.
Best regards,
Wolfgang Denk

Thanks for your input.I agree completely. This part was only included for reference. And the entire series is an RFC.
On Thu, Aug 5, 2010 at 4:35 PM, Wolfgang Denk wd@denx.de wrote:
Dear John Rigby,
In message 1281046488-25187-4-git-send-email-john.rigby@linaro.org you wrote:
This is just for testing ARM device tree support. There is no device tree enabled arm kernel at the moment.
Signed-off-by: John Rigby john.rigby@linaro.org
MAKEALL | 1 + boards.cfg | 1 + include/configs/omap3_beagle_dt.h | 344 +++++++++++++++++++++++++++++++++++++ 3 files changed, 346 insertions(+), 0 deletions(-) create mode 100644 include/configs/omap3_beagle_dt.h
NAK.
Please do not add a separate config file where only 9 out of 344 lines are different from the existing one.
Best regards,
Wolfgang Denk
-- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de We have found all life forms in the galaxy are capable of superior development. -- Kirk, "The Gamesters of Triskelion", stardate 3211.7 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Here is a new version of patches for adding device tree support for ARM. I have tried to address all comments made to the previous RFC patch series.
John Rigby (5): FDT: Add fixup support for multiple banks of memory FDT: only call boot_get_fdt from generic code boot: change some arch ifdefs to feature ifdefs ARM: add flat device tree support ARM: enable device tree for beagle
arch/arm/include/asm/config.h | 2 + arch/arm/lib/bootm.c | 138 ++++++++++++++++++++++++++++++++---- arch/m68k/include/asm/config.h | 3 + arch/microblaze/lib/bootm.c | 12 +--- arch/nios2/lib/bootm.c | 10 +-- arch/powerpc/include/asm/config.h | 3 + arch/sparc/include/asm/config.h | 1 + common/cmd_bootm.c | 4 +- common/fdt_support.c | 86 ++++++++++++----------- common/image.c | 12 ++- include/configs/omap3_beagle.h | 10 ++- include/fdt_support.h | 1 + include/image.h | 9 ++- 13 files changed, 207 insertions(+), 84 deletions(-)

Add fdt_fixup_memory_banks and reimplement fdt_fixup_memory using it.
Signed-off-by: John Rigby john.rigby@linaro.org --- common/fdt_support.c | 86 ++++++++++++++++++++++++++----------------------- include/fdt_support.h | 1 + 2 files changed, 47 insertions(+), 40 deletions(-)
diff --git a/common/fdt_support.c b/common/fdt_support.c index 33336be..0b07534 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -362,10 +362,40 @@ void do_fixup_by_compat_u32(void *fdt, const char *compat, do_fixup_by_compat(fdt, compat, prop, &val, 4, create); }
-int fdt_fixup_memory(void *blob, u64 start, u64 size) +/* + * Get cells len in bytes + * if #NNNN-cells property is 2 then len is 8 + * otherwise len is 4 + */ +static int get_cells_len(void *blob, char *nr_cells_name) +{ + const u32 *cell; + + cell = fdt_getprop(blob, 0, nr_cells_name, NULL); + if (cell && *cell == 2) + return 8; + + return 4; +} + +/* + * Write a 4 or 8 byte big endian cell + */ +static void write_cell(u8 *addr, u64 val, int size) { - int err, nodeoffset, len = 0; - u8 tmp[16]; + int shift = (size - 1) * 8; + while (size-- > 0) { + *addr++ = (val >> shift) & 0xff; + shift -= 8; + } +} + +int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks) +{ + int err, nodeoffset; + int addr_cell_len, size_cell_len, len; + u8 tmp[banks * 8]; + int bank; const u32 *addrcell, *sizecell;
err = fdt_check_header(blob); @@ -391,44 +421,15 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size) return err; }
- addrcell = fdt_getprop(blob, 0, "#address-cells", NULL); - /* use shifts and mask to ensure endianness */ - if ((addrcell) && (*addrcell == 2)) { - tmp[0] = (start >> 56) & 0xff; - tmp[1] = (start >> 48) & 0xff; - tmp[2] = (start >> 40) & 0xff; - tmp[3] = (start >> 32) & 0xff; - tmp[4] = (start >> 24) & 0xff; - tmp[5] = (start >> 16) & 0xff; - tmp[6] = (start >> 8) & 0xff; - tmp[7] = (start ) & 0xff; - len = 8; - } else { - tmp[0] = (start >> 24) & 0xff; - tmp[1] = (start >> 16) & 0xff; - tmp[2] = (start >> 8) & 0xff; - tmp[3] = (start ) & 0xff; - len = 4; - } + addr_cell_len = get_cells_len(blob, "#address-cells"); + size_cell_len = get_cells_len(blob, "#size-cells");
- sizecell = fdt_getprop(blob, 0, "#size-cells", NULL); - /* use shifts and mask to ensure endianness */ - if ((sizecell) && (*sizecell == 2)) { - tmp[0+len] = (size >> 56) & 0xff; - tmp[1+len] = (size >> 48) & 0xff; - tmp[2+len] = (size >> 40) & 0xff; - tmp[3+len] = (size >> 32) & 0xff; - tmp[4+len] = (size >> 24) & 0xff; - tmp[5+len] = (size >> 16) & 0xff; - tmp[6+len] = (size >> 8) & 0xff; - tmp[7+len] = (size ) & 0xff; - len += 8; - } else { - tmp[0+len] = (size >> 24) & 0xff; - tmp[1+len] = (size >> 16) & 0xff; - tmp[2+len] = (size >> 8) & 0xff; - tmp[3+len] = (size ) & 0xff; - len += 4; + for (bank = 0, len = 0; bank < banks; bank++) { + write_cell(tmp + len, start, addr_cell_len); + len += addr_cell_len; + + write_cell(tmp + len, start, size_cell_len); + len += size_cell_len; }
err = fdt_setprop(blob, nodeoffset, "reg", tmp, len); @@ -440,6 +441,11 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size) return 0; }
+int fdt_fixup_memory(void *blob, u64 start, u64 size) +{ + return fdt_fixup_memory_banks(blob, &start, &size, 1); +} + void fdt_fixup_ethernet(void *fdt) { int node, i, j; diff --git a/include/fdt_support.h b/include/fdt_support.h index 871ef45..5f631ea 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -48,6 +48,7 @@ void do_fixup_by_compat(void *fdt, const char *compat, void do_fixup_by_compat_u32(void *fdt, const char *compat, const char *prop, u32 val, int create); int fdt_fixup_memory(void *blob, u64 start, u64 size); +int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks); void fdt_fixup_ethernet(void *fdt); int fdt_find_and_setprop(void *fdt, const char *node, const char *prop, const void *val, int len, int create);

All arches except nios2 and microblaze call boot_get_fdt from bootm_start in common/cmd_bootm.c.
Having nios2 and microblaze do so as well removes code from their respective do_bootm_linux routines and allows removal of a nasty ifdef from bootm_start.
Signed-off-by: John Rigby john.rigby@linaro.org --- arch/microblaze/lib/bootm.c | 12 +++--------- arch/nios2/lib/bootm.c | 10 +++------- common/cmd_bootm.c | 2 -- 3 files changed, 6 insertions(+), 18 deletions(-)
diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index 8e2c6d8..25f63d9 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -46,12 +46,9 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima
char *of_flat_tree = NULL; #if defined(CONFIG_OF_LIBFDT) - ulong of_size = 0; - - /* find flattened device tree */ - ret = boot_get_fdt (flag, argc, argv, images, &of_flat_tree, &of_size); - if (ret) - return 1; + /* did generic code already find a device tree? */ + if (images->ft_len) + of_flat_tree = images->ft_addr; #endif
theKernel = (void (*)(char *, ulong, ulong))images->ep; @@ -64,9 +61,6 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima
show_boot_progress (15);
- if (!(ulong) of_flat_tree) - of_flat_tree = (char *)simple_strtoul (argv[3], NULL, 16); - #ifdef DEBUG printf ("## Transferring control to Linux (at address 0x%08lx) " \ "ramdisk 0x%08lx, FDT 0x%08lx...\n", diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c index e25a113..1ff6f0a 100644 --- a/arch/nios2/lib/bootm.c +++ b/arch/nios2/lib/bootm.c @@ -36,14 +36,10 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima ulong initrd_end = images->rd_end; char *of_flat_tree = NULL; #if defined(CONFIG_OF_LIBFDT) - ulong of_size = 0; - - /* find flattened device tree */ - if (boot_get_fdt(flag, argc, argv, images, &of_flat_tree, &of_size)) - return 1; + /* did generic code already find a device tree? */ + if (images->ft_len) + of_flat_tree = images->ft_addr; #endif - if (!of_flat_tree) - of_flat_tree = (char *)simple_strtoul(argv[3], NULL, 16); if (of_flat_tree) initrd_end = (ulong)of_flat_tree;
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 4c6ed48..f12e2d1 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -301,7 +301,6 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] }
#if defined(CONFIG_OF_LIBFDT) -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) /* find flattened device tree */ ret = boot_get_fdt (flag, argc, argv, &images, &images.ft_addr, &images.ft_len); @@ -312,7 +311,6 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
set_working_fdt_addr(images.ft_addr); #endif -#endif }
images.os.start = (ulong)os_hdr;

The routines boot_ramdisk_high, boot_get_cmdline and boot_get_kbd are currently enabled by various combinations of CONFIG_M68K, CONFIG_POWERPC and CONFIG_SPARC.
Use CONFIG_<FEATURE> defines instead.
CONFIG_BOOT_RAMDISK_HIGH CONFIG_BOOT_GET_CMDLINE CONFIG_BOOT_GET_KBD
Define these as appropriate in arch/include/asm/config.h files.
Signed-off-by: John Rigby john.rigby@linaro.org --- arch/m68k/include/asm/config.h | 3 +++ arch/powerpc/include/asm/config.h | 3 +++ arch/sparc/include/asm/config.h | 1 + common/cmd_bootm.c | 2 +- common/image.c | 10 ++++++---- include/image.h | 9 ++++++--- 6 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/arch/m68k/include/asm/config.h b/arch/m68k/include/asm/config.h index 36438be..1fbdf0a 100644 --- a/arch/m68k/include/asm/config.h +++ b/arch/m68k/include/asm/config.h @@ -22,5 +22,8 @@ #define _ASM_CONFIG_H_
#define CONFIG_LMB +#define CONFIG_BOOT_RAMDISK_HIGH +#define CONFIG_BOOT_GET_CMDLINE +#define CONFIG_BOOT_GET_KBD
#endif diff --git a/arch/powerpc/include/asm/config.h b/arch/powerpc/include/asm/config.h index d098657..788f27d 100644 --- a/arch/powerpc/include/asm/config.h +++ b/arch/powerpc/include/asm/config.h @@ -22,6 +22,9 @@ #define _ASM_CONFIG_H_
#define CONFIG_LMB +#define CONFIG_BOOT_RAMDISK_HIGH +#define CONFIG_BOOT_GET_CMDLINE +#define CONFIG_BOOT_GET_KBD
#ifndef CONFIG_MAX_MEM_MAPPED #if defined(CONFIG_4xx) || defined(CONFIG_E500) || defined(CONFIG_MPC86xx) diff --git a/arch/sparc/include/asm/config.h b/arch/sparc/include/asm/config.h index 36438be..b072771 100644 --- a/arch/sparc/include/asm/config.h +++ b/arch/sparc/include/asm/config.h @@ -22,5 +22,6 @@ #define _ASM_CONFIG_H_
#define CONFIG_LMB +#define CONFIG_BOOT_RAMDISK_HIGH
#endif diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index f12e2d1..9ad82e2 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -521,7 +521,7 @@ int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); break; -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#ifdef CONFIG_BOOT_RAMDISK_HIGH case BOOTM_STATE_RAMDISK: { ulong rd_len = images.rd_end - images.rd_start; diff --git a/common/image.c b/common/image.c index fcb938b..6b1ee6b 100644 --- a/common/image.c +++ b/common/image.c @@ -991,7 +991,7 @@ int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images, return 0; }
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#ifdef CONFIG_BOOT_RAMDISK_HIGH /** * boot_ramdisk_high - relocate init ramdisk * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1080,7 +1080,7 @@ int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, error: return -1; } -#endif /* defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) */ +#endif /* CONFIG_BOOT_RAMDISK_HIGH */
#ifdef CONFIG_OF_LIBFDT static void fdt_error (const char *msg) @@ -1587,7 +1587,7 @@ error: } #endif /* CONFIG_OF_LIBFDT */
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +#ifdef CONFIG_BOOT_GET_CMDLINE /** * boot_get_cmdline - allocate and initialize kernel cmdline * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1629,7 +1629,9 @@ int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
return 0; } +#endif /* CONFIG_BOOT_GET_CMDLINE */
+#ifdef CONFIG_BOOT_GET_KBD /** * boot_get_kbd - allocate and initialize kernel copy of board info * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1662,7 +1664,7 @@ int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base)
return 0; } -#endif /* CONFIG_PPC || CONFIG_M68K */ +#endif /* CONFIG_BOOT_GET_KBD */ #endif /* !USE_HOSTCC */
#if defined(CONFIG_FIT) diff --git a/include/image.h b/include/image.h index bcc08d1..e94c15d 100644 --- a/include/image.h +++ b/include/image.h @@ -339,14 +339,17 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, char **of_flat_tree, ulong *of_size); #endif
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +#ifdef CONFIG_BOOT_RAMDISK_HIGH int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, ulong *initrd_start, ulong *initrd_end); - +#endif /* CONFIG_BOOT_RAMDISK_HIGH */ +#ifdef CONFIG_BOOT_GET_CMDLINE int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, ulong bootmap_base); +#endif /* CONFIG_BOOT_GET_CMDLINE */ +#ifdef CONFIG_BOOT_GET_KBD int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base); -#endif /* CONFIG_PPC || CONFIG_M68K */ +#endif /* CONFIG_BOOT_GET_KBD */ #endif /* !USE_HOSTCC */
/*******************************************************************/

Based on other architectures already supported.
Signed-off-by: John Rigby john.rigby@linaro.org --- arch/arm/include/asm/config.h | 2 + arch/arm/lib/bootm.c | 138 ++++++++++++++++++++++++++++++++++++----- common/image.c | 2 + 3 files changed, 126 insertions(+), 16 deletions(-)
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index b76fd8e..ca3a367 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -23,5 +23,7 @@
/* Relocation to SDRAM works on all ARM boards */ #define CONFIG_RELOC_FIXUP_WORKS +#define CONFIG_LMB +#define CONFIG_BOOT_RAMDISK_HIGH
#endif diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 3101321..d4e2502 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -27,6 +27,10 @@ #include <u-boot/zlib.h> #include <asm/byteorder.h>
+#include <fdt.h> +#include <libfdt.h> +#include <fdt_support.h> + DECLARE_GLOBAL_DATA_PTR;
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ @@ -50,12 +54,52 @@ static void setup_end_tag (bd_t *bd); static struct tag *params; #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
-int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images) +static ulong get_sp(void); +#if defined(CONFIG_OF_LIBFDT) +static int bootm_linux_fdt(bootm_headers_t *images); +#endif + +void arch_lmb_reserve(struct lmb *lmb) +{ + ulong sp; + + /* + * Booting a (Linux) kernel image + * + * Allocate space for command line and board info - the + * address should be as high as possible within the reach of + * the kernel (see CONFIG_SYS_BOOTMAPSZ settings), but in unused + * memory, which means far enough below the current stack + * pointer. + */ + sp = get_sp(); + debug("## Current stack ends at 0x%08lx ", sp); + + /* adjust sp by 1K to be safe */ + sp -= 1024; + lmb_reserve(lmb, sp, + gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp); +} + +static void announce_and_cleanup(void) +{ + printf("\nStarting kernel ...\n\n"); + +#ifdef CONFIG_USB_DEVICE + { + extern void udc_disconnect(void); + udc_disconnect(); + } +#endif + cleanup_before_linux(); +} + +int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) { bd_t *bd = gd->bd; char *s; int machid = bd->bi_arch_number; - void (*theKernel)(int zero, int arch, uint params); + void (*kernel_entry)(int zero, int arch, uint params);
#ifdef CONFIG_CMDLINE_TAG char *commandline = getenv ("bootargs"); @@ -64,8 +108,6 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) return 1;
- theKernel = (void (*)(int, int, uint))images->ep; - s = getenv ("machid"); if (s) { machid = simple_strtoul (s, NULL, 16); @@ -74,8 +116,15 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima
show_boot_progress (15);
+#ifdef CONFIG_OF_LIBFDT + if (images->ft_len) + return bootm_linux_fdt(machid, images); +#endif + + kernel_entry = (void (*)(int, int, uint))images->ep; + debug ("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) theKernel); + (ulong) kernel_entry);
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ @@ -99,27 +148,76 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima if (images->rd_start && images->rd_end) setup_initrd_tag (bd, images->rd_start, images->rd_end); #endif - setup_end_tag (bd); + setup_end_tag(bd); #endif
- /* we assume that the kernel is in place */ - printf ("\nStarting kernel ...\n\n"); + announce_and_cleanup();
-#ifdef CONFIG_USB_DEVICE - { - extern void udc_disconnect (void); - udc_disconnect (); + kernel_entry(0, machid, bd->bi_boot_params); + /* does not return */ + + return 1; +} + +#if defined(CONFIG_OF_LIBFDT) +static int fixup_memory_node(void *blob) +{ + bd_t *bd = gd->bd; + int bank; + u64 start[CONFIG_NR_DRAM_BANKS]; + u64 size[CONFIG_NR_DRAM_BANKS]; + + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { + start[bank] = bd->bi_dram[bank].start; + size[bank] = bd->bi_dram[bank].size; } -#endif
- cleanup_before_linux (); + return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); +} + +static int bootm_linux_fdt(int machid, bootm_headers_t *images) +{ + ulong rd_len; + bd_t *bd = gd->bd; + char *s; + void (*kernel_entry)(int zero, int dt_machid, void *dtblob); + ulong bootmap_base = getenv_bootm_low(); + ulong of_size = images->ft_len; + char **of_flat_tree = &images->ft_addr; + ulong *initrd_start = &images->initrd_start; + ulong *initrd_end = &images->initrd_end; + struct lmb *lmb = &images->lmb; + int ret; + + kernel_entry = (void (*)(int, int, void *))images->ep; + + rd_len = images->rd_end - images->rd_start; + ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, + initrd_start, initrd_end); + if (ret) + return ret;
- theKernel (0, machid, bd->bi_boot_params); + ret = boot_relocate_fdt(lmb, bootmap_base, of_flat_tree, &of_size); + if (ret) + return ret; + + debug("## Transferring control to Linux (at address %08lx) ...\n", + (ulong) kernel_entry); + + fdt_chosen(*of_flat_tree, 1); + + fixup_memory_node(*of_flat_tree); + + fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1); + + announce_and_cleanup(); + + kernel_entry(0, machid, *of_flat_tree); /* does not return */
return 1; } - +#endif
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ @@ -239,4 +337,12 @@ static void setup_end_tag (bd_t *bd) params->hdr.size = 0; }
+static ulong get_sp(void) +{ + ulong ret; + + asm("mov %0, sp" : "=r"(ret) : ); + return ret; +} + #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ diff --git a/common/image.c b/common/image.c index 6b1ee6b..9b0b57b 100644 --- a/common/image.c +++ b/common/image.c @@ -1213,9 +1213,11 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, if (fdt_blob < (char *)bootmap_base) relocate = 1;
+#ifdef CONFIG_SYS_BOOTMAPSZ if ((fdt_blob + *of_size + CONFIG_SYS_FDT_PAD) >= ((char *)CONFIG_SYS_BOOTMAPSZ + bootmap_base)) relocate = 1; +#endif
/* move flattend device tree if needed */ if (relocate) {

On 09/01/2010 11:53 AM, John Rigby wrote:
Based on other architectures already supported.
Signed-off-by: John Rigbyjohn.rigby@linaro.org
Tested-by: Rob Herring rob.herring@smooth-stone.com

For testing ARM device tree support
Signed-off-by: John Rigby john.rigby@linaro.org --- include/configs/omap3_beagle.h | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h index ae5a791..6bd3c7b 100644 --- a/include/configs/omap3_beagle.h +++ b/include/configs/omap3_beagle.h @@ -55,6 +55,9 @@ #undef CONFIG_USE_IRQ /* no support for IRQs */ #define CONFIG_MISC_INIT_R
+#define CONFIG_OF_LIBFDT 1 +#define CONFIG_SYS_BOOTMAPSZ (8 << 20) + #define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ #define CONFIG_SETUP_MEMORY_TAGS 1 #define CONFIG_INITRD_TAG 1 @@ -148,6 +151,7 @@ #define CONFIG_SYS_I2C_BUS 0 #define CONFIG_SYS_I2C_BUS_SELECT 1 #define CONFIG_DRIVER_OMAP34XX_I2C 1 +#define CONFIG_I2C_MULTI_BUS 1
/* * TWL4030 @@ -158,6 +162,7 @@ /* * Board NAND Info. */ +#define CONFIG_SYS_NAND_QUIET_TEST 1 #define CONFIG_NAND_OMAP_GPMC #define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */ /* to access nand */ @@ -183,6 +188,7 @@ "loadaddr=0x82000000\0" \ "usbtty=cdc_acm\0" \ "console=ttyS2,115200n8\0" \ + "mpurate=500\0" \ "vram=12M\0" \ "dvimode=1024x768MR-16@60\0" \ "defaultdisplay=dvi\0" \ @@ -191,16 +197,16 @@ "nandroot=/dev/mtdblock4 rw\0" \ "nandrootfstype=jffs2\0" \ "mmcargs=setenv bootargs console=${console} " \ + "mpurate=${mpurate} " \ "vram=${vram} " \ "omapfb.mode=dvi:${dvimode} " \ - "omapfb.debug=y " \ "omapdss.def_disp=${defaultdisplay} " \ "root=${mmcroot} " \ "rootfstype=${mmcrootfstype}\0" \ "nandargs=setenv bootargs console=${console} " \ + "mpurate=${mpurate} " \ "vram=${vram} " \ "omapfb.mode=dvi:${dvimode} " \ - "omapfb.debug=y " \ "omapdss.def_disp=${defaultdisplay} " \ "root=${nandroot} " \ "rootfstype=${nandrootfstype}\0" \

Sorry, ignore this patch it has some left over cruft from a rebase.
On Wed, Sep 1, 2010 at 10:53 AM, John Rigby john.rigby@linaro.org wrote:
For testing ARM device tree support
Signed-off-by: John Rigby john.rigby@linaro.org
participants (12)
-
Albert ARIBAUD
-
Can Aydin
-
Dan Malek
-
Grant Likely
-
John Rigby
-
John Rigby
-
Kumar Gala
-
Reinhard Meyer
-
Rob Herring
-
Scott Wood
-
Wolfgang Denk
-
Xie Shaohui-B21989