|
@@ -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
|