Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Apr 2014 00:31:32 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r265068 - in stable/10/sys/boot: common fdt
Message-ID:  <201404290031.s3T0VWt1026659@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Tue Apr 29 00:31:32 2014
New Revision: 265068
URL: http://svnweb.freebsd.org/changeset/base/265068

Log:
  MFC r262340, r262345, r262347, find and load an appropriate dtb file.
  
  The search order for a usable dtb in fdt_setup_fdtp() is now
  
   - A dtb loaded with an explicit "load -t dtb" command.
   - A dtb already loaded into memory somehow[*] and pointed to by fdt_to_load.
   - A dtb in the memory pointed to by the u-boot env vars fdtaddr or fdt_addr.
   - A file named by the u-boot env vars fdtfile or fdt_file.
   - A static dtb compiled into the kernel.
  
   * Presumably by some arch-specific command or code.

Modified:
  stable/10/sys/boot/common/bootstrap.h
  stable/10/sys/boot/common/module.c
  stable/10/sys/boot/fdt/fdt_loader_cmd.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/boot/common/bootstrap.h
==============================================================================
--- stable/10/sys/boot/common/bootstrap.h	Tue Apr 29 00:17:30 2014	(r265067)
+++ stable/10/sys/boot/common/bootstrap.h	Tue Apr 29 00:31:32 2014	(r265068)
@@ -233,6 +233,7 @@ int			mod_loadkld(const char *name, int 
 struct preloaded_file *file_alloc(void);
 struct preloaded_file *file_findfile(char *name, char *type);
 struct file_metadata *file_findmetadata(struct preloaded_file *fp, int type);
+struct preloaded_file *file_loadraw(char *name, char *type);
 void file_discard(struct preloaded_file *fp);
 void file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p);
 int  file_addmodule(struct preloaded_file *fp, char *modname, int version,

Modified: stable/10/sys/boot/common/module.c
==============================================================================
--- stable/10/sys/boot/common/module.c	Tue Apr 29 00:17:30 2014	(r265067)
+++ stable/10/sys/boot/common/module.c	Tue Apr 29 00:31:32 2014	(r265068)
@@ -52,7 +52,6 @@ struct moduledir {
 };
 
 static int			file_load(char *filename, vm_offset_t dest, struct preloaded_file **result);
-static int			file_loadraw(char *type, char *name);
 static int			file_load_dependencies(struct preloaded_file *base_mod);
 static char *			file_search(const char *name, char **extlist);
 static struct kernel_module *	file_findmodule(struct preloaded_file *fp, char *modname, struct mod_depend *verinfo);
@@ -134,7 +133,7 @@ command_load(int argc, char *argv[])
 	    command_errmsg = "invalid load type";
 	    return(CMD_ERROR);
 	}
-	return(file_loadraw(typestr, argv[1]));
+	return(file_loadraw(argv[1], typestr) ? CMD_OK : CMD_ERROR);
     }
     /*
      * Do we have explicit KLD load ?
@@ -189,7 +188,7 @@ command_load_geli(int argc, char *argv[]
     argv += (optind - 1);
     argc -= (optind - 1);
     sprintf(typestr, "%s:geli_keyfile%d", argv[1], num);
-    return(file_loadraw(typestr, argv[2]));
+    return(file_loadraw(argv[2], typestr) ? CMD_OK : CMD_ERROR);
 }
 
 COMMAND_SET(unload, "unload", "unload all modules", command_unload);
@@ -357,8 +356,8 @@ file_load_dependencies(struct preloaded_
  * We've been asked to load (name) as (type), so just suck it in,
  * no arguments or anything.
  */
-int
-file_loadraw(char *type, char *name)
+struct preloaded_file *
+file_loadraw(char *name, char *type)
 {
     struct preloaded_file	*fp;
     char			*cp;
@@ -368,21 +367,21 @@ file_loadraw(char *type, char *name)
     /* We can't load first */
     if ((file_findfile(NULL, NULL)) == NULL) {
 	command_errmsg = "can't load file before kernel";
-	return(CMD_ERROR);
+	return(NULL);
     }
 
     /* locate the file on the load path */
     cp = file_search(name, NULL);
     if (cp == NULL) {
 	sprintf(command_errbuf, "can't find '%s'", name);
-	return(CMD_ERROR);
+	return(NULL);
     }
     name = cp;
 
     if ((fd = open(name, O_RDONLY)) < 0) {
 	sprintf(command_errbuf, "can't open '%s': %s", name, strerror(errno));
 	free(name);
-	return(CMD_ERROR);
+	return(NULL);
     }
 
     if (archsw.arch_loadaddr != NULL)
@@ -398,7 +397,7 @@ file_loadraw(char *type, char *name)
 	    sprintf(command_errbuf, "error reading '%s': %s", name, strerror(errno));
 	    free(name);
 	    close(fd);
-	    return(CMD_ERROR);
+	    return(NULL);
 	}
 	laddr += got;
     }
@@ -419,7 +418,7 @@ file_loadraw(char *type, char *name)
     /* Add to the list of loaded files */
     file_insert_tail(fp);
     close(fd);
-    return(CMD_OK);
+    return(fp);
 }
 
 /*

Modified: stable/10/sys/boot/fdt/fdt_loader_cmd.c
==============================================================================
--- stable/10/sys/boot/fdt/fdt_loader_cmd.c	Tue Apr 29 00:17:30 2014	(r265067)
+++ stable/10/sys/boot/fdt/fdt_loader_cmd.c	Tue Apr 29 00:31:32 2014	(r265068)
@@ -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) {
@@ -248,6 +254,32 @@ fdt_load_dtb_addr(struct fdt_header *hea
 }
 
 static int
+fdt_load_dtb_file(const char * filename)
+{
+	struct preloaded_file *bfp, *oldbfp;
+	int err;
+
+	debugf("fdt_load_dtb_file(%s)\n", filename);
+
+	oldbfp = file_findfile(NULL, "dtb");
+
+	/* Attempt to load and validate a new dtb from a file. */
+	if ((bfp = file_loadraw(filename, "dtb")) == NULL) {
+		sprintf(command_errbuf, "failed to load file '%s'", filename);
+		return (1);
+	}
+	if ((err = fdt_load_dtb(bfp->f_addr)) != 0) {
+		file_discard(bfp);
+		return (err);
+	}
+
+	/* A new dtb was validated, discard any previous file. */
+	if (oldbfp)
+		file_discard(oldbfp);
+	return (0);
+}
+
+static int
 fdt_setup_fdtp()
 {
 	struct preloaded_file *bfp;
@@ -256,35 +288,68 @@ fdt_setup_fdtp()
 	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 '%s'.\n", 
+			    bfp->f_name);
+			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%p.\n", hdr);
+				return (0);
+			}
 		}
 	}
-	
+
+	/*
+	 * If the U-boot environment contains a variable giving the name of a
+	 * file, use it if we can load and validate it.
+	 */
+	s = ub_env_get("fdtfile");
+	if (s == NULL)
+		s = ub_env_get("fdt_file");
+	if (s != NULL && *s != '\0') {
+		if (fdt_load_dtb_file(s) == 0) {
+			printf("Loaded DTB from file '%s'.\n", s);
+			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 +743,8 @@ fdt_fixup(void)
 	ethstr = NULL;
 	len = 0;
 
+	debugf("fdt_fixup()\n");
+
 	if (fdtp == NULL && fdt_setup_fdtp() != 0)
 		return (0);
 
@@ -741,7 +808,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?201404290031.s3T0VWt1026659>