Add a flattened device tree (fdt) command (2 of 2)

Modifications to the existing code to support the new fdt command.
This commit is contained in:
Gerald Van Baren 2007-03-31 12:23:51 -04:00
parent 781e09ee6e
commit 213bf8c822
8 changed files with 237 additions and 27 deletions

33
README
View File

@ -164,6 +164,7 @@ Directory Hierarchy:
- lib_mips Files generic to MIPS architecture - lib_mips Files generic to MIPS architecture
- lib_nios Files generic to NIOS architecture - lib_nios Files generic to NIOS architecture
- lib_ppc Files generic to PowerPC architecture - lib_ppc Files generic to PowerPC architecture
- libfdt Library files to support flattened device trees
- net Networking code - net Networking code
- post Power On Self Test - post Power On Self Test
- rtc Real Time Clock drivers - rtc Real Time Clock drivers
@ -430,12 +431,23 @@ The following options need to be configured:
expect it to be in bytes, others in MB. expect it to be in bytes, others in MB.
Define CONFIG_MEMSIZE_IN_BYTES to make it in bytes. Define CONFIG_MEMSIZE_IN_BYTES to make it in bytes.
CONFIG_OF_FLAT_TREE CONFIG_OF_LIBFDT / CONFIG_OF_FLAT_TREE
New kernel versions are expecting firmware settings to be New kernel versions are expecting firmware settings to be
passed using flat open firmware trees. passed using flattened device trees (based on open firmware
The environment variable "disable_of", when set, disables this concepts).
functionality.
CONFIG_OF_LIBFDT
* New libfdt-based support
* Adds the "fdt" command
* The bootm command does _not_ modify the fdt
CONFIG_OF_FLAT_TREE
* Deprecated, see CONFIG_OF_LIBFDT
* Original ft_build.c-based support
* Automatically modifies the dft as part of the bootm command
* The environment variable "disable_of", when set,
disables this functionality.
CONFIG_OF_FLAT_TREE_MAX_SIZE CONFIG_OF_FLAT_TREE_MAX_SIZE
@ -448,13 +460,16 @@ The following options need to be configured:
CONFIG_OF_HAS_BD_T CONFIG_OF_HAS_BD_T
The resulting flat device tree will have a copy of the bd_t. * CONFIG_OF_LIBFDT - enables the "fdt bd_t" command
Space should be pre-allocated in the dts for the bd_t. * CONFIG_OF_FLAT_TREE - The resulting flat device tree
will have a copy of the bd_t. Space should be
pre-allocated in the dts for the bd_t.
CONFIG_OF_HAS_UBOOT_ENV CONFIG_OF_HAS_UBOOT_ENV
The resulting flat device tree will have a copy of u-boot's * CONFIG_OF_LIBFDT - enables the "fdt bd_t" command
environment variables * CONFIG_OF_FLAT_TREE - The resulting flat device tree
will have a copy of u-boot's environment variables
CONFIG_OF_BOARD_SETUP CONFIG_OF_BOARD_SETUP
@ -721,6 +736,8 @@ The following options need to be configured:
#define CONFIG_COMMANDS (CFG_CMD_ALL & ~CFG_CMD_NET) #define CONFIG_COMMANDS (CFG_CMD_ALL & ~CFG_CMD_NET)
Other Commands:
fdt (flattened device tree) command: CONFIG_OF_LIBFDT
Note: Don't enable the "icache" and "dcache" commands Note: Don't enable the "icache" and "dcache" commands
(configuration option CFG_CMD_CACHE) unless you know (configuration option CFG_CMD_CACHE) unless you know

View File

@ -26,3 +26,9 @@
# #
TEXT_BASE = 0xFE000000 TEXT_BASE = 0xFE000000
#
# Additional board-specific libraries
#
BOARDLIBS = libfdt/libfdt.a

View File

@ -31,6 +31,10 @@
#if defined(CONFIG_OF_FLAT_TREE) #if defined(CONFIG_OF_FLAT_TREE)
#include <ft_build.h> #include <ft_build.h>
#endif #endif
#if defined(CONFIG_OF_LIBFDT)
#include <libfdt.h>
#include <libfdt_env.h>
#endif
const qe_iop_conf_t qe_iop_conf_tab[] = { const qe_iop_conf_t qe_iop_conf_tab[] = {
/* GETH1 */ /* GETH1 */
@ -658,22 +662,36 @@ U_BOOT_CMD(ecc, 4, 0, do_ecc,
" - disables injects\n" " - re-inits memory"); " - disables injects\n" " - re-inits memory");
#endif /* if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) */ #endif /* if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) */
#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) #if (defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)) \
&& defined(CONFIG_OF_BOARD_SETUP)
void void
ft_board_setup(void *blob, bd_t *bd) ft_board_setup(void *blob, bd_t *bd)
{ {
#if defined(CONFIG_OF_LIBFDT)
int nodeoffset;
int err;
int tmp[2];
nodeoffset = fdt_path_offset (fdt, "/memory");
if (nodeoffset >= 0) {
tmp[0] = cpu_to_be32(bd->bi_memstart);
tmp[1] = cpu_to_be32(bd->bi_memsize);
err = fdt_setprop(fdt, nodeoffset, "reg", tmp, sizeof(tmp));
}
#else
u32 *p; u32 *p;
int len; int len;
#ifdef CONFIG_PCI
ft_pci_setup(blob, bd);
#endif
ft_cpu_setup(blob, bd);
p = ft_get_prop(blob, "/memory/reg", &len); p = ft_get_prop(blob, "/memory/reg", &len);
if (p != NULL) { if (p != NULL) {
*p++ = cpu_to_be32(bd->bi_memstart); *p++ = cpu_to_be32(bd->bi_memstart);
*p = cpu_to_be32(bd->bi_memsize); *p = cpu_to_be32(bd->bi_memsize);
} }
#endif
#ifdef CONFIG_PCI
ft_pci_setup(blob, bd);
#endif
ft_cpu_setup(blob, bd);
} }
#endif #endif

View File

@ -21,6 +21,10 @@
#if defined(CONFIG_OF_FLAT_TREE) #if defined(CONFIG_OF_FLAT_TREE)
#include <ft_build.h> #include <ft_build.h>
#endif #endif
#if defined(CONFIG_OF_LIBFDT)
#include <libfdt.h>
#include <libfdt_env.h>
#endif
#include <asm/fsl_i2c.h> #include <asm/fsl_i2c.h>
@ -299,6 +303,22 @@ void pci_init_board(void)
} }
#endif /* CONFIG_PCISLAVE */ #endif /* CONFIG_PCISLAVE */
#if defined(CONFIG_OF_LIBFDT)
void
ft_pci_setup(void *blob, bd_t *bd)
{
int nodeoffset;
int err;
int tmp[2];
nodeoffset = fdt_path_offset (fdt, "/" OF_SOC "/pci@8500");
if (nodeoffset >= 0) {
tmp[0] = cpu_to_be32(hose[0].first_busno);
tmp[1] = cpu_to_be32(hose[0].last_busno);
err = fdt_setprop(fdt, nodeoffset, "bus-range", tmp, sizeof(tmp));
}
}
#endif /* CONFIG_OF_LIBFDT */
#ifdef CONFIG_OF_FLAT_TREE #ifdef CONFIG_OF_FLAT_TREE
void void
ft_pci_setup(void *blob, bd_t *bd) ft_pci_setup(void *blob, bd_t *bd)

View File

@ -32,7 +32,7 @@ COBJS = main.o ACEX1K.o altera.o bedbug.o circbuf.o cmd_autoscript.o \
cmd_cache.o cmd_console.o \ cmd_cache.o cmd_console.o \
cmd_date.o cmd_dcr.o cmd_diag.o cmd_display.o cmd_doc.o cmd_dtt.o \ cmd_date.o cmd_dcr.o cmd_diag.o cmd_display.o cmd_doc.o cmd_dtt.o \
cmd_eeprom.o cmd_elf.o cmd_ext2.o \ cmd_eeprom.o cmd_elf.o cmd_ext2.o \
cmd_fat.o cmd_fdc.o cmd_fdos.o cmd_flash.o cmd_fpga.o \ cmd_fat.o cmd_fdc.o cmd_fdt.o cmd_fdos.o cmd_flash.o cmd_fpga.o \
cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \ cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \
cmd_load.o cmd_log.o \ cmd_load.o cmd_log.o \
cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \ cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \

View File

@ -34,7 +34,11 @@
#include <environment.h> #include <environment.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#ifdef CONFIG_OF_FLAT_TREE #if defined(CONFIG_OF_LIBFDT)
#include <fdt.h>
#include <libfdt.h>
#endif
#if defined(CONFIG_OF_FLAT_TREE)
#include <ft_build.h> #include <ft_build.h>
#endif #endif
@ -467,7 +471,7 @@ U_BOOT_CMD(
"[addr [arg ...]]\n - boot application image stored in memory\n" "[addr [arg ...]]\n - boot application image stored in memory\n"
"\tpassing arguments 'arg ...'; when booting a Linux kernel,\n" "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
"\t'arg' can be the address of an initrd image\n" "\t'arg' can be the address of an initrd image\n"
#ifdef CONFIG_OF_FLAT_TREE #if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
"\tWhen booting a Linux kernel which requires a flat device-tree\n" "\tWhen booting a Linux kernel which requires a flat device-tree\n"
"\ta third argument is required which is the address of the of the\n" "\ta third argument is required which is the address of the of the\n"
"\tdevice-tree blob. To boot that kernel without an initrd image,\n" "\tdevice-tree blob. To boot that kernel without an initrd image,\n"
@ -529,7 +533,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
bd_t *kbd; bd_t *kbd;
void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); void (*kernel)(bd_t *, ulong, ulong, ulong, ulong);
image_header_t *hdr = &header; image_header_t *hdr = &header;
#ifdef CONFIG_OF_FLAT_TREE #if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
char *of_flat_tree = NULL; char *of_flat_tree = NULL;
ulong of_data = 0; ulong of_data = 0;
#endif #endif
@ -622,7 +626,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
* Check if there is an initrd image * Check if there is an initrd image
*/ */
#ifdef CONFIG_OF_FLAT_TREE #if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
/* Look for a '-' which indicates to ignore the ramdisk argument */ /* Look for a '-' which indicates to ignore the ramdisk argument */
if (argc >= 3 && strcmp(argv[2], "-") == 0) { if (argc >= 3 && strcmp(argv[2], "-") == 0) {
debug ("Skipping initrd\n"); debug ("Skipping initrd\n");
@ -739,12 +743,15 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
len = data = 0; len = data = 0;
} }
#ifdef CONFIG_OF_FLAT_TREE #if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
if(argc > 3) { if(argc > 3) {
of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16);
hdr = (image_header_t *)of_flat_tree; hdr = (image_header_t *)of_flat_tree;
#if defined(CONFIG_OF_LIBFDT)
if (*(ulong *)of_flat_tree == OF_DT_HEADER) { if (be32_to_cpu(fdt_magic(of_flat_tree)) == FDT_MAGIC) {
#else
if (*(ulong *)of_flat_tree == OF_DT_HEADER) {
#endif
#ifndef CFG_NO_FLASH #ifndef CFG_NO_FLASH
if (addr2info((ulong)of_flat_tree) != NULL) if (addr2info((ulong)of_flat_tree) != NULL)
of_data = (ulong)of_flat_tree; of_data = (ulong)of_flat_tree;
@ -787,7 +794,11 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
printf("ERROR: uImage is not uncompressed\n"); printf("ERROR: uImage is not uncompressed\n");
return; return;
} }
#if defined(CONFIG_OF_LIBFDT)
if (be32_to_cpu(fdt_magic(of_flat_tree + sizeof(image_header_t))) != FDT_MAGIC) {
#else
if (*((ulong *)(of_flat_tree + sizeof(image_header_t))) != OF_DT_HEADER) { if (*((ulong *)(of_flat_tree + sizeof(image_header_t))) != OF_DT_HEADER) {
#endif
printf ("ERROR: uImage data is not a flat device tree\n"); printf ("ERROR: uImage data is not a flat device tree\n");
return; return;
} }
@ -824,12 +835,20 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
of_data += 4 - tail; of_data += 4 - tail;
} }
#if defined(CONFIG_OF_LIBFDT)
if (be32_to_cpu(fdt_magic(of_data)) != FDT_MAGIC) {
#else
if (((struct boot_param_header *)of_data)->magic != OF_DT_HEADER) { if (((struct boot_param_header *)of_data)->magic != OF_DT_HEADER) {
#endif
printf ("ERROR: image is not a flat device tree\n"); printf ("ERROR: image is not a flat device tree\n");
return; return;
} }
#if defined(CONFIG_OF_LIBFDT)
if (be32_to_cpu(fdt_totalsize(of_data)) != ntohl(len_ptr[2])) {
#else
if (((struct boot_param_header *)of_data)->totalsize != ntohl(len_ptr[2])) { if (((struct boot_param_header *)of_data)->totalsize != ntohl(len_ptr[2])) {
#endif
printf ("ERROR: flat device tree size does not agree with image\n"); printf ("ERROR: flat device tree size does not agree with image\n");
return; return;
} }
@ -913,7 +932,31 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
unlock_ram_in_cache(); unlock_ram_in_cache();
#endif #endif
#ifdef CONFIG_OF_FLAT_TREE #if defined(CONFIG_OF_LIBFDT)
/* move of_flat_tree if needed */
if (of_data) {
int err;
ulong of_start, of_len;
of_len = be32_to_cpu(fdt_totalsize(of_data));
/* provide extra 8k pad */
if (initrd_start)
of_start = initrd_start - of_len - 8192;
else
of_start = (ulong)kbd - of_len - 8192;
of_start &= ~(4096 - 1); /* align on page */
debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
of_data, of_data + of_len - 1, of_len, of_len);
printf (" Loading Device Tree to %08lx, end %08lx ... ",
of_start, of_start + of_len - 1);
err = fdt_open_into(of_start, of_data, of_len);
if (err != 0) {
printf ("libfdt: %s\n", fdt_strerror(err));
}
}
#endif
#if defined(CONFIG_OF_FLAT_TREE)
/* move of_flat_tree if needed */ /* move of_flat_tree if needed */
if (of_data) { if (of_data) {
ulong of_start, of_len; ulong of_start, of_len;
@ -942,13 +985,13 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
* r6: Start of command line string * r6: Start of command line string
* r7: End of command line string * r7: End of command line string
*/ */
#ifdef CONFIG_OF_FLAT_TREE #if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
if (!of_flat_tree) /* no device tree; boot old style */ if (!of_flat_tree) /* no device tree; boot old style */
#endif #endif
(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
/* does not return */ /* does not return */
#ifdef CONFIG_OF_FLAT_TREE #if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
/* /*
* Linux Kernel Parameters (passing device tree): * Linux Kernel Parameters (passing device tree):
* r3: ptr to OF flat tree, followed by the board info data * r3: ptr to OF flat tree, followed by the board info data
@ -957,8 +1000,10 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
* r6: NULL * r6: NULL
* r7: NULL * r7: NULL
*/ */
#if defined(CONFIG_OF_FLAT_TREE)
ft_setup(of_flat_tree, kbd, initrd_start, initrd_end); ft_setup(of_flat_tree, kbd, initrd_start, initrd_end);
/* ft_dump_blob(of_flat_tree); */ /* ft_dump_blob(of_flat_tree); */
#endif
(*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0);
#endif #endif

View File

@ -30,8 +30,14 @@
#include <watchdog.h> #include <watchdog.h>
#include <command.h> #include <command.h>
#include <mpc83xx.h> #include <mpc83xx.h>
#include <ft_build.h>
#include <asm/processor.h> #include <asm/processor.h>
#if defined(CONFIG_OF_FLAT_TREE)
#include <ft_build.h>
#endif
#if defined(CONFIG_OF_LIBFDT)
#include <libfdt.h>
#include <libfdt_env.h>
#endif
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
@ -291,6 +297,100 @@ void watchdog_reset (void)
} }
#endif #endif
#if defined(CONFIG_OF_LIBFDT)
/*
* Fixups to the fdt. If "create" is TRUE, the node is created
* unconditionally. If "create" is FALSE, the node is updated
* only if it already exists.
*/
#define FT_UPDATE 0x00000000 /* update existing property only */
#define FT_CREATE 0x00000001 /* create property if it doesn't exist */
#define FT_BUSFREQ 0x00000002 /* source is bd->bi_busfreq */
#define FT_ENETADDR 0x00000004 /* source is bd->bi_enetaddr */
static const struct {
int createflags;
char *node;
char *prop;
} fixup_props[] = {
{ FT_CREATE | FT_BUSFREQ,
"/cpus/" OF_CPU,
"bus-frequency",
},
{ FT_CREATE | FT_BUSFREQ,
"/cpus/" OF_SOC,
"bus-frequency"
},
{ FT_CREATE | FT_BUSFREQ,
"/" OF_SOC "/serial@4500/",
"clock-frequency"
},
{ FT_CREATE | FT_BUSFREQ,
"/" OF_SOC "/serial@4600/",
"clock-frequency"
},
#ifdef CONFIG_MPC83XX_TSEC1
{ FT_UPDATE | FT_ENETADDR,
"/" OF_SOC "/ethernet@24000,
"mac-address",
},
{ FT_UPDATE | FT_ENETADDR,
"/" OF_SOC "/ethernet@24000,
"local-mac-address",
},
#endif
#ifdef CONFIG_MPC83XX_TSEC2
{ FT_UPDATE | FT_ENETADDR,
"/" OF_SOC "/ethernet@25000,
"mac-address",
},
{ FT_UPDATE | FT_ENETADDR,
"/" OF_SOC "/ethernet@25000,
"local-mac-address",
},
#endif
};
void
ft_cpu_setup(void *blob, bd_t *bd)
{
int nodeoffset;
int err;
int j;
for (j = 0; j < (sizeof(fixup_props) / sizeof(fixup_props[0])); j++) {
nodeoffset = fdt_path_offset (fdt, fixup_props[j].node);
if (nodeoffset >= 0) {
/*
* If unconditional create or the property already exists...
*/
if ((fixup_props[j].createflags & FT_CREATE) ||
(fdt_get_property(fdt, nodeoffset, fixup_props[j].prop, 0))) {
if (fixup_props[j].createflags & FT_BUSFREQ) {
u32 tmp;
tmp = cpu_to_be32(bd->bi_busfreq);
err = fdt_setprop(fdt, nodeoffset,
fixup_props[j].prop, &tmp, sizeof(tmp));
} else if (fixup_props[j].createflags & FT_ENETADDR) {
err = fdt_setprop(fdt, nodeoffset,
fixup_props[j].prop, bd->bi_enetaddr, 6);
} else {
printf("ft_cpu_setup: %s %s has no flag for the value to set\n",
fixup_props[j].node,
fixup_props[j].prop);
}
if (err < 0)
printf("libfdt: %s %s returned %s\n",
fixup_props[j].node,
fixup_props[j].prop,
fdt_strerror(err));
}
}
}
}
#endif
#if defined(CONFIG_OF_FLAT_TREE) #if defined(CONFIG_OF_FLAT_TREE)
void void
ft_cpu_setup(void *blob, bd_t *bd) ft_cpu_setup(void *blob, bd_t *bd)

View File

@ -342,8 +342,12 @@
#endif #endif
/* pass open firmware flat tree */ /* pass open firmware flat tree */
#define CONFIG_OF_FLAT_TREE 1 #define CONFIG_OF_LIBFDT 1
#undef CONFIG_OF_FLAT_TREE
#define CONFIG_OF_BOARD_SETUP 1 #define CONFIG_OF_BOARD_SETUP 1
#define CONFIG_OF_HAS_BD_T 1
#define CONFIG_OF_HAS_UBOOT_ENV 1
/* maximum size of the flat tree (8K) */ /* maximum size of the flat tree (8K) */
#define OF_FLAT_TREE_MAX_SIZE 8192 #define OF_FLAT_TREE_MAX_SIZE 8192