Add common memory fixup function
RFC PATCH 1/1 Add common memory fixup function
Guys,
Here's my cut at a more generic version of Martin's patch that respects #ac and #sc.
Let me know what you think and if you have any comments. I'll add the board bits in a complete patch if this looks ok.
- k
common/fdt_support.c +60 -0
@@ -441,6 +441,66 @@ 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) +{ +int i, err, nodeoffset, len =0 ; +u8 tmp[16 ]; +const u32 *addrcell, *sizecell; + + err =fdt_check_header (blob); +if (err <0 ) { +printf ("%s: %s\n" , __FUNCTION__,fdt_strerror (err)); +return err; + } + +/* update, or add and update /memory node */ + nodeoffset =fdt_path_offset (blob,"/memory" ); +if (nodeoffset <0 ) { + nodeoffset =fdt_add_subnode (blob,0 ,"memory" ); +if (nodeoffset <0 ) +printf ("WARNING: could not create /memory: %s.\n" , +fdt_strerror (nodeoffset)); +return nodeoffset; + } + err =fdt_setprop (blob, nodeoffset,"device_type" ,"memory" , +sizeof ("memory" )); +if (err <0 ) { +printf ("WARNING: could not set %s %s.\n" ,"device_type" , +fdt_strerror (err)); +return err; + } + + addrcell =fdt_getprop (blob,0 ,"#address-cells" ,NULL ); +if ((addrcell) && (*addrcell ==2 )) { +for (i =0 ; i <=7 ; i++) + tmp[i] = (start >> ((7 - i) *8 )) &0xff ; + len =8 ; + }else { +for (i =0 ; i <=3 ; i++) + tmp[i] = (start >> ((3 - i) *8 )) &0xff ; + len =4 ; + } + + sizecell =fdt_getprop (blob,0 ,"#size-cells" ,NULL ); +if ((sizecell) && (*sizecell ==2 )) { +for (i =0 ; i <=7 ; i++) + tmp[i+len] = (size >> ((7 - i) *8 )) &0xff ; + len +=8 ; + }else { +for (i =0 ; i <=3 ; i++) + tmp[i+len] = (size >> ((3 - i) *8 )) &0xff ; + len +=4 ; + } + + err =fdt_setprop (fdt, nodeoffset,"reg" , tmp, len); +if (err <0 ) { +printf ("WARNING: could not set %s %s.\n" , +"reg" ,fdt_strerror (err)); +return err; + } +return 0 ; +} +void fdt_fixup_ethernet (void *fdt,bd_t *bd) {int node;
include/fdt_support.h +1 -0
@@ -44,6 +44,7 @@ void do_fixup_by_compat(void *fdt, const char *compat, const char *prop, const void *val, int len, int create);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);void fdt_fixup_ethernet (void *fdt,bd_t *bd);#ifdef CONFIG_OF_HAS_UBOOT_ENV
RFC PATCH 1/1 Add common memory fixup function
Quoted 8 lines · On Mon, 26 Nov 2007 14:55:46 -0600 (CST) Kumar Gala wrote:
Guys,
Here's my cut at a more generic version of Martin's patch that respects #ac and #sc.
Let me know what you think and if you have any comments. I'll add the board bits in a complete patch if this looks ok.
funny, I did the same with slightly different approach. below goes my version...
I think we are different only in #ac/#sc accounting, so let the people consider the best approach :)
Or... am I wrong in something?
----
fdt: add common memory fixup function
From: Martin Krause <[email protected]>
Add the function fdt_memory() to fixup the /memory node of the fdt with the memory values detected by U-Boot (taken from bd->bi_memstart and bd->bi_memsize).
The new function is called for all boards which define CONFIG_OF_LIBFDT.
This patch removes already existing board specific memory fixup routines for boards wich have CONFIG_OF_LIBFDT defined and switches them to the new routine. Boards wich use the CONIFG_OF_FLAT_TREE method are not touched.
---
README | 9 +++++ board/cds/common/ft_board.c | 9 ----- board/cm5200/cm5200.c | 23 ++----------- common/cmd_bootm.c | 12 +++++++ common/fdt_support.c | 75 +++++++++++++++++++++++++++++++++++++++++++ cpu/mpc83xx/cpu.c | 20 ++--------- include/fdt_support.h | 1 + 7 files changed, 103 insertions(+), 46 deletions(-)
README +9 -0
@@ -335,6 +335,15 @@ The following options need to be configured: passed using flattened device trees (based on open firmware concepts). + CONFIG_OF_MEMORY_FIXUP + + While using CONFIG_OF_LIBFDT above, each board needs special + /memory node set up in fdt with proper values. This config + option makes it auto-updated during bootm command. In some + cases, when HW requires "specific" crafting of /memory node, + or it is desired to have this step processed from BSP part + explicitly, this option should be disabled. + CONFIG_OF_LIBFDT * New libfdt-based support * Adds the "fdt" command
board/cds/common/ft_board.c +0 -9
@@ -63,20 +63,11 @@ static void cds_pci_fixup(void *blob)void ft_board_setup (void *blob,bd_t *bd) { -u32 *p; -int len; -#ifdef CONFIG_PCI ft_pci_setup (blob, bd);#endif ft_cpu_setup (blob, bd); - p =ft_get_prop (blob,"/memory/reg" , &len); -if (p !=NULL ) { - *p++ =cpu_to_be32 (bd->bi_memstart); - *p =cpu_to_be32 (bd->bi_memsize); - } -cds_pci_fixup (blob); }#endif
board/cm5200/cm5200.c +3 -20
@@ -256,14 +256,13 @@ static void compose_hostname(hw_id_t hw_id, char *buf)#if defined(CONFIG_OF_BOARD_SETUP ) && defined(CONFIG_OF_LIBFDT )/* -* Update 'model' and 'memory' properties in the blob according to the module -* that we are running on. +* Update 'model' property in the blob according to the module that we are +* running on. */ static void ft_blob_update (void *blob,bd_t *bd) {int len, ret, nodeoffset =0 ;char module_name[MODULE_NAME_MAXLEN ] = {0 }; -ulong memory_data[2 ] = {0 };compose_module_name (hw_id, module_name); len =strlen (module_name) +1 ;
@@ -272,23 +271,6 @@ static void ft_blob_update(void *blob, bd_t *bd)if (ret <0 )printf ("ft_blob_update(): cannot set /model property err:%s\n" , fdt_strerror(ret)); - - memory_data[0 ] =cpu_to_be32 (bd->bi_memstart); - memory_data[1 ] =cpu_to_be32 (bd->bi_memsize); - - nodeoffset =fdt_find_node_by_path (blob,"/memory" ); -if (nodeoffset >=0 ) { - ret =fdt_setprop (blob, nodeoffset,"reg" , memory_data, -sizeof (memory_data)); -if (ret <0 ) -printf ("ft_blob_update): cannot set /memory/reg " -"property err:%s\n" ,fdt_strerror (ret)); - } -else { -/* memory node is required in dts */ -printf ("ft_blob_update(): cannot find /memory node " -"err:%s\n" ,fdt_strerror (nodeoffset)); - } }#endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */
@@ -422,5 +404,6 @@ void ft_board_setup(void *blob, bd_t *bd) {ft_cpu_setup (blob, bd);ft_blob_update (blob, bd); +fdt_memory (blob); }#endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */
common/cmd_bootm.c +12 -0
@@ -992,6 +992,18 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, do_reset (cmdtp, flag, argc, argv); }#endif +#ifdef CONFIG_OF_MEMORY_FIXUP +/* +* Add the "/memory" node if it does not exist, and do a fixup +* of the "reg" property with values detected by U-Boot +* (taken from bd->bi_memstart and bd->bi_memsize). +*/ +if (fdt_memory (of_flat_tree) <0 ) { +puts ("ERROR: /memory node create failed - " +"must RESET the board to recover.\n" ); +do_reset (cmdtp, flag, argc, argv); + } +#endif #ifdef CONFIG_OF_BOARD_SETUP /* Call the board-specific fixup routine */ ft_board_setup (of_flat_tree, gd->bd);
common/fdt_support.c +75 -0
79 lines not on this page · raw message
cpu/mpc83xx/cpu.c +3 -17
@@ -526,7 +526,6 @@ ft_cpu_setup(void *blob, bd_t *bd)int nodeoffset;int err;int j; -int tmp[2 ];for (j =0 ; j < (sizeof (fixup_props) /sizeof (fixup_props[0 ])); j++) { nodeoffset =fdt_find_node_by_path (blob, fixup_props[j].node);
@@ -542,22 +541,6 @@ ft_cpu_setup(void *blob, bd_t *bd) fixup_props[j].node, fdt_strerror(nodeoffset)); } } - -/* update, or add and update /memory node */ - nodeoffset =fdt_find_node_by_path (blob,"/memory" ); -if (nodeoffset <0 ) { - nodeoffset =fdt_add_subnode (blob,0 ,"memory" ); -if (nodeoffset <0 ) -debug ("failed to add /memory node: %s\n" , -fdt_strerror (nodeoffset)); - } -if (nodeoffset >=0 ) { -fdt_setprop (blob, nodeoffset,"device_type" , -"memory" ,sizeof ("memory" )); - tmp[0 ] =cpu_to_be32 (bd->bi_memstart); - tmp[1 ] =cpu_to_be32 (bd->bi_memsize); -fdt_setprop (blob, nodeoffset,"reg" , tmp,sizeof (tmp)); - } }#elif defined(CONFIG_OF_FLAT_TREE)void
@@ -567,6 +550,9 @@ ft_cpu_setup(void *blob, bd_t *bd)int len;ulong clock; +/* fixup/create /memory node */ +fdt_memory (blob); + clock = bd->bi_busfreq; p =ft_get_prop (blob,"/cpus/" OF_CPU "/bus-frequency" , &len);if (p !=NULL )
include/fdt_support.h +1 -0
@@ -29,6 +29,7 @@#include <fdt.h> int fdt_chosen (void *fdt,ulong initrd_start,ulong initrd_end,int force); +int fdt_memory (void *fdt);#ifdef CONFIG_OF_HAS_UBOOT_ENV int fdt_env (void *fdt);
Signature · 1 line
Sincerely, Vitaly
RFC PATCH 1/1 Add common memory fixup function
Quoted 13 lines
+/ ********************************************************************/
(quoted diff) +2
-0+ +static int ft_get_property_int(void *blob, char *path, const char*prop)
common/fdt_support.c +7
-0+{ +int offset, len; +void *ptr; +u32 dst; + + offset =fdt_find_node_by_path (blob, path); + ptr =fdt_getprop (blob, offset, prop, &len);
common/fdt_support.c int fdt_bd_t(void *fdt) · line 370
Quoted 10 lines
common/fdt_support.c +10
-0+debug ("%s(): got %d size %d\n" , __FUNCTION__, ptr, len); +if ((ptr) && (len ==sizeof (int ))) { +memcpy (&dst, ptr, len); +debug ("dest %d\n" , dst); +return dst; + } +return -1 ; +} + +int fdt_memory (void *fdt)
I want it to be passed start and size rather than grabbing them directly. I have future applications in which using the same function will be useful.
Quoted 29 lines
common/fdt_support.c +29
-0+{ +int nodeoffset; +int err; +u32 tmp[4 ]; +bd_t *bd = gd->bd; + + err =fdt_check_header (fdt); +if (err <0 ) { +printf ("fdt_memory: %s\n" ,fdt_strerror (err)); +return err; + } + +memset (tmp,0 ,sizeof (tmp)); +/* Now, figure out toplevel #ac and #sc - we'll need them later */ + offset =fdt_find_node_by_path (fdt,"/" ); + ac =ft_get_property_int (fdt,"/" ,"#address-cells" ); + sc =ft_get_property_int (fdt,"/" ,"#size-cells" ); +debug ("#address-cells=%d size-cells=%d\n" , ac, sc); + +/* update, or add and update /memory node */ + nodeoffset =fdt_find_node_by_path (fdt,"/memory" ); +if (nodeoffset <0 ) { + nodeoffset =fdt_add_subnode (fdt,0 ,"memory" ); +if (nodeoffset <0 ) +printf ("WARNING could not create /memory: %s.\n" , +fdt_strerror (nodeoffset)); +return nodeoffset; + } + err = fdt_setprop(fdt, nodeoffset, "device_type", "memory",
common/fdt_support.c int fdt_bd_t(void *fdt) · line 409
Quoted 10 lines
common/fdt_support.c +10
-0+ sizeof("memory")); +if (err <0 ) { +printf ("WARNING: could not set %s %s.\n" , +"device_type" ,fdt_strerror (err)); +return err; + } + +/* this is a little rashly, but as long as u-boot is keeping +* memstart and memsize as ulong, should be safe. +*/
Hmm, I think this is a bad assumption. (We are looking at 36-bit phys support on e500 & e600).
Quoted 17 lines
common/fdt_support.c +16
-0+if ((ac >=1 ) || (sc >=1 )) +debug ("ulong memory params while #ac=%d and #sc=%d\n" , + ac, sc); + tmp[ac-1 ] =cpu_to_fdt32 (bd->bi_memstart); + tmp[ac+sc-1 ] =cpu_to_fdt32 (bd->bi_memsize); + + err = fdt_setprop(blob, offset, "reg", + tmp, (ac+sc)*sizeof(tmp[0]))) +if (err <0 ) { +printf ("WARNING: could not set %s %s.\n" , +"reg" ,fdt_strerror (err)); +return err; + } +return 0 ; +} +#endif /*
CONFIG_OF_LIBFDT*/
RFC PATCH 1/1 Add common memory fixup function
Quoted 7 lines · On Mon, 26 Nov 2007 16:23:10 -0600 Kumar Gala wrote:
common/fdt_support.c int fdt_bd_t(void *fdt) · line 409
Quoted 4 lines
(quoted diff) +1
-0+ /* this is a little rashly, but as long as u-boot iskeeping
common/fdt_support.c +2
-0+* memstart and memsize as ulong, should be safe. +*/ Hmm, I think this is a bad assumption. (We are looking at 36-bit phys support on e500 & e600).
I'll look at it once again, from u64 POW, as was discussed....
Signature · 1 line
Sincerely, Vitaly
RFC PATCH 1/1 Add common memory fixup function
In reply to Vitaly BordugHi Vitaly,
Vitaly Bordug wrote on Monday, November 26, 2007 11:12 PM:
Quoted 50 lines
Quoted 8 lines · On Mon, 26 Nov 2007 14:55:46 -0600 (CST) Kumar Gala wrote:
Guys,
Here's my cut at a more generic version of Martin's patch that respects #ac and #sc.
Let me know what you think and if you have any comments. I'll add the board bits in a complete patch if this looks ok.
funny, I did the same with slightly different approach. below goes my version...
I think we are different only in #ac/#sc accounting, so let the people consider the best approach :)
Or... am I wrong in something?
----fdt: add common memory fixup function
From: Martin Krause <[email protected]>
Add the function
fdt_memory()to fixup the /memory node of the fdt with the memory values detected by U-Boot (taken frombd->bi_memstartandbd->bi_memsize).The new function is called for all boards which define
CONFIG_OF_LIBFDT.This patch removes already existing board specific memory fixup routines
for boards wich haveCONFIG_OF_LIBFDTdefined and switches them to the new routine. Boards wich use theCONIFG_OF_FLAT_TREEmethod are not touched.Signed-off-by Martin Krause <[email protected]>Signed-off-by Vitaly Bordug <[email protected]>---
README | 9 +++++ board/cds/common/ft_board.c | 9 ----- board/cm5200/cm5200.c | 23 ++----------- common/cmd_bootm.c | 12 +++++++ common/fdt_support.c | 75 +++++++++++++++++++++++++++++++++++++++++++ cpu/mpc83xx/cpu.c | 20 ++--------- include/fdt_support.h | 1 + 7 files changed, 103 insertions(+), 46 deletions(-)
[...]
Quoted 10 lines
common/cmd_bootm.c +2
-0@@ -992,6 +992,18 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, do_reset (cmdtp, flag, argc, argv); }#endif +#ifdef CONFIG_OF_MEMORY_FIXUP +/*
common/cmd_bootm.c do_bootm_linux (cmd_tbl_t *cmdtp, int flag, · line 1006
Quoted 10 lines
common/cmd_bootm.c +10
-0+* Add the "/memory" node if it does not exist, and do a fixup +* of the "reg" property with values detected by U-Boot +* (taken from bd->bi_memstart and bd->bi_memsize). +*/ +if (fdt_memory (of_flat_tree) <0 ) { +puts ("ERROR: /memory node create failed - " +"must RESET the board to recover.\n" ); +do_reset (cmdtp, flag, argc, argv); + } +#endif
Ah, you placed a CONFIG_OF_MEMORY_FIXUP around the fdt_memory() call. That's OK with me, but then please set this define for all boards, which did a memory fixup already. I can't remeber, which boards this were exactly, but I know that the TQM5200 was one of it :-).
Best Regards,
Martin Krause
RFC PATCH 1/1 Add common memory fixup function
In reply to Kumar GalaKumar Gala wrote on Monday, November 26, 2007 9:56 PM:
Quoted 6 lines
Guys,
Here's my cut at a more generic version of Martin's patch that respects #ac and #sc.
Let me know what you think and if you have any comments. I'll add the
Looks fine to me.
Best Regards,
Martin Krause
RFC PATCH 1/1 Add common memory fixup function
In reply to Kumar GalaKumar Gala wrote on Monday, November 26, 2007 9:56 PM:
Quoted 37 lines
common/fdt_support.c +29
-0@@ -441,6 +441,66 @@ 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) +{ +int i, err, nodeoffset, len =0 ; +u8 tmp[16 ]; +const u32 *addrcell, *sizecell; + + err =fdt_check_header (blob); +if (err <0 ) { +printf ("%s: %s\n" , __FUNCTION__,fdt_strerror (err)); +return err; + } + +/* update, or add and update /memory node */ + nodeoffset =fdt_path_offset (blob,"/memory" ); +if (nodeoffset <0 ) { + nodeoffset =fdt_add_subnode (blob,0 ,"memory" ); +if (nodeoffset <0 ) +printf ("WARNING: could not create /memory: %s.\n" , +fdt_strerror (nodeoffset)); +return nodeoffset; + } + err =fdt_setprop (blob, nodeoffset,"device_type" ,"memory" , +sizeof ("memory" )); +if (err <0 ) { +printf ("WARNING: could not set %s %s.\n" ,"device_type" , +fdt_strerror (err)); +return err; + } +
common/fdt_support.c void do_fixup_by_compat_u32(void *fdt, const · line 482
Quoted 10 lines
common/fdt_support.c +10
-0+ addrcell =fdt_getprop (blob,0 ,"#address-cells" ,NULL ); +if ((addrcell) && (*addrcell ==2 )) { +for (i =0 ; i <=7 ; i++) + tmp[i] = (start >> ((7 - i) *8 )) &0xff ; + len =8 ; + }else { +for (i =0 ; i <=3 ; i++) + tmp[i] = (start >> ((3 - i) *8 )) &0xff ; + len =4 ; + }
Could this perhaps lead to endianess issues under some special circumstances?
Best Regards,
Martin Krause
RFC PATCH 1/1 Add common memory fixup function
Quoted 14 lines · Martin Krause
Kumar Gala wrote on Monday, November 26, 2007 9:56 PM:
common/fdt_support.c void do_fixup_by_compat_u32(void *fdt, const char *compat, · line 482
Quoted 10 lines
common/fdt_support.c +10
-0+ addrcell =fdt_getprop (blob,0 ,"#address-cells" ,NULL ); +if ((addrcell) && (*addrcell ==2 )) { +for (i =0 ; i <=7 ; i++) + tmp[i] = (start >> ((7 - i) *8 )) &0xff ; + len =8 ; + }else { +for (i =0 ; i <=3 ; i++) + tmp[i] = (start >> ((3 - i) *8 )) &0xff ; + len =4 ; + }Could this perhaps lead to endianess issues under some special circumstances?
I don't think so -- the device tree is defined as always being big-endian, regardless of the host endianness (multi-cell values would get a bit weird otherwise).
-Scott