|
|
|
@ -24,13 +24,11 @@ |
|
|
|
|
#include <common.h> |
|
|
|
|
#include <linux/ctype.h> |
|
|
|
|
#include <linux/types.h> |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_OF_LIBFDT |
|
|
|
|
|
|
|
|
|
#include <asm/global_data.h> |
|
|
|
|
#include <fdt.h> |
|
|
|
|
#include <libfdt.h> |
|
|
|
|
#include <fdt_support.h> |
|
|
|
|
#include <exports.h> |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Global data (for the gd->bd) |
|
|
|
@ -70,6 +68,43 @@ int fdt_find_and_setprop(void *fdt, const char *node, const char *prop, |
|
|
|
|
return fdt_setprop(fdt, nodeoff, prop, val, len); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_OF_STDOUT_VIA_ALIAS |
|
|
|
|
static int fdt_fixup_stdout(void *fdt, int choosenoff) |
|
|
|
|
{ |
|
|
|
|
int err = 0; |
|
|
|
|
#ifdef CONFIG_CONS_INDEX |
|
|
|
|
int node; |
|
|
|
|
char sername[9] = { 0 }; |
|
|
|
|
const char *path; |
|
|
|
|
|
|
|
|
|
sprintf(sername, "serial%d", CONFIG_CONS_INDEX - 1); |
|
|
|
|
|
|
|
|
|
err = node = fdt_path_offset(fdt, "/aliases"); |
|
|
|
|
if (node >= 0) { |
|
|
|
|
int len; |
|
|
|
|
path = fdt_getprop(fdt, node, sername, &len); |
|
|
|
|
if (path) { |
|
|
|
|
char *p = malloc(len); |
|
|
|
|
err = -FDT_ERR_NOSPACE; |
|
|
|
|
if (p) { |
|
|
|
|
memcpy(p, path, len); |
|
|
|
|
err = fdt_setprop(fdt, choosenoff, |
|
|
|
|
"linux,stdout-path", p, len); |
|
|
|
|
free(p); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
err = len; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
if (err < 0) |
|
|
|
|
printf("WARNING: could not set linux,stdout-path %s.\n", |
|
|
|
|
fdt_strerror(err)); |
|
|
|
|
|
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force) |
|
|
|
|
{ |
|
|
|
|
int nodeoffset; |
|
|
|
@ -160,6 +195,11 @@ int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force) |
|
|
|
|
printf("WARNING: could not set linux,initrd-end %s.\n", |
|
|
|
|
fdt_strerror(err)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_OF_STDOUT_VIA_ALIAS |
|
|
|
|
err = fdt_fixup_stdout(fdt, nodeoffset); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifdef OF_STDOUT_PATH |
|
|
|
|
err = fdt_setprop(fdt, nodeoffset, |
|
|
|
|
"linux,stdout-path", OF_STDOUT_PATH, strlen(OF_STDOUT_PATH)+1); |
|
|
|
@ -441,6 +481,87 @@ 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 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); |
|
|
|
|
/* 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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
err = fdt_setprop(blob, nodeoffset, "reg", tmp, len); |
|
|
|
|
if (err < 0) { |
|
|
|
|
printf("WARNING: could not set %s %s.\n", |
|
|
|
|
"reg", fdt_strerror(err)); |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if defined(CONFIG_HAS_ETH0) || defined(CONFIG_HAS_ETH1) ||\ |
|
|
|
|
defined(CONFIG_HAS_ETH2) || defined(CONFIG_HAS_ETH3) |
|
|
|
|
|
|
|
|
|
void fdt_fixup_ethernet(void *fdt, bd_t *bd) |
|
|
|
|
{ |
|
|
|
|
int node; |
|
|
|
@ -486,5 +607,4 @@ void fdt_fixup_ethernet(void *fdt, bd_t *bd) |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif /* CONFIG_OF_LIBFDT */ |
|
|
|
|
#endif |
|
|
|
|