Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 22 Feb 2014 19:10:59 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r262340 - head/sys/boot/fdt
Message-ID:  <201402221910.s1MJAx1G003248@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Sat Feb 22 19:10:58 2014
New Revision: 262340
URL: http://svnweb.freebsd.org/changeset/base/262340

Log:
  Change fdt_setup_fdtp() from "guess then fail" to more probe-like behavior.
  
  The old code basically said it was going to use some particular blob
  without knowing whether it could successfully do so, then it would invoke
  the function to do that and return its status.  If it failed, you were
  done, even if other blobs might be available.  Now the code attempts to use
  some particular blob and if that succeeds it says so and returns success,
  otherwise it moves on to try another potential blob.
  
  One specific problem this solves is when u-boot sets an fdtaddr variable
  to point to some memory address, then doesn't actually load a blob at
  that address.  Now the header check will fail, and the code will move
  on to the fallback dtb compiled into the kernel (if any).

Modified:
  head/sys/boot/fdt/fdt_loader_cmd.c

Modified: head/sys/boot/fdt/fdt_loader_cmd.c
==============================================================================
--- head/sys/boot/fdt/fdt_loader_cmd.c	Sat Feb 22 18:55:49 2014	(r262339)
+++ head/sys/boot/fdt/fdt_loader_cmd.c	Sat Feb 22 19:10:58 2014	(r262340)
@@ -128,6 +128,8 @@ fdt_find_static_dtb()
 	char *strp;
 	int i, sym_count;
 
+	debugf("fdt_find_static_dtb()\n");
+
 	sym_count = symtab = strtab = 0;
 	strp = NULL;
 
@@ -189,6 +191,8 @@ fdt_load_dtb(vm_offset_t va)
 	struct fdt_header header;
 	int err;
 
+	debugf("fdt_load_dtb(0x%08jx)\n", (uintmax_t)va);
+
 	COPYOUT(va, &header, sizeof(header));
 	err = fdt_check_header(&header);
 	if (err < 0) {
@@ -229,6 +233,8 @@ fdt_load_dtb_addr(struct fdt_header *hea
 {
 	int err;
 
+	debugf("fdt_load_dtb_addr(0x%p)\n", header);
+
 	fdtp_size = fdt_totalsize(header);
 	err = fdt_check_header(header);
 	if (err < 0) {
@@ -252,39 +258,58 @@ fdt_setup_fdtp()
 {
 	struct preloaded_file *bfp;
 	struct fdt_header *hdr;
+	int err;
 	const char *s;
 	char *p;
 	vm_offset_t va;
 	
+	debugf("fdt_setup_fdtp()\n");
+
+	/* If we already loaded a file, use it. */
 	if ((bfp = file_findfile(NULL, "dtb")) != NULL) {
-		printf("Using DTB from loaded file.\n");
-		return fdt_load_dtb(bfp->f_addr);
+		if (fdt_load_dtb(bfp->f_addr) == 0) {
+			printf("Using DTB from loaded file.\n");
+			return (0);
+		}
 	}
-	
+
+	/* If we were given the address of a valid blob in memory, use it. */
 	if (fdt_to_load != NULL) {
-		printf("Using DTB from memory address 0x%08X.\n",
-		    (unsigned int)fdt_to_load);
-		return fdt_load_dtb_addr(fdt_to_load);
+		if (fdt_load_dtb_addr(fdt_to_load) == 0) {
+			printf("Using DTB from memory address 0x%08X.\n",
+			    (unsigned int)fdt_to_load);
+			return (0);
+		}
 	}
 
-	/* Board vendors use both fdtaddr and fdt_addr names.  Grrrr. */
+	/*
+	 * If the U-boot environment contains a variable giving the address of a
+	 * valid blob in memory, use it.  Board vendors use both fdtaddr and
+	 * fdt_addr names.
+	 */
 	s = ub_env_get("fdtaddr");
 	if (s == NULL)
 		s = ub_env_get("fdt_addr");
 	if (s != NULL && *s != '\0') {
 		hdr = (struct fdt_header *)strtoul(s, &p, 16);
 		if (*p == '\0') {
-			printf("Using DTB provided by U-Boot.\n");
-			return fdt_load_dtb_addr(hdr);
+			if (fdt_load_dtb_addr(hdr) == 0) {
+				printf("Using DTB provided by U-Boot at "
+				    "address 0x%08X.\n", hdr);
+				return (0);
+			}
 		}
 	}
-	
+
+	/* If there is a dtb compiled into the kernel, use it. */
 	if ((va = fdt_find_static_dtb()) != 0) {
-		printf("Using DTB compiled into kernel.\n");
-		return (fdt_load_dtb(va));
+		if (fdt_load_dtb(va) == 0) {
+			printf("Using DTB compiled into kernel.\n");
+			return (0);
+		}
 	}
 	
-	command_errmsg = "no device tree blob found!";
+	command_errmsg = "No device tree blob found!\n";
 	return (1);
 }
 
@@ -678,6 +703,8 @@ fdt_fixup(void)
 	ethstr = NULL;
 	len = 0;
 
+	debugf("fdt_fixup()\n");
+
 	if (fdtp == NULL && fdt_setup_fdtp() != 0)
 		return (0);
 
@@ -741,7 +768,7 @@ int
 fdt_copy(vm_offset_t va)
 {
 	int err;
-
+	debugf("fdt_copy va 0x%08x\n", va);
 	if (fdtp == NULL) {
 		err = fdt_setup_fdtp();
 		if (err) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201402221910.s1MJAx1G003248>