summaryrefslogtreecommitdiffstats
path: root/sys/boot/fdt/fdt_loader_cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/boot/fdt/fdt_loader_cmd.c')
-rw-r--r--sys/boot/fdt/fdt_loader_cmd.c138
1 files changed, 104 insertions, 34 deletions
diff --git a/sys/boot/fdt/fdt_loader_cmd.c b/sys/boot/fdt/fdt_loader_cmd.c
index a5613ae..1d74d62 100644
--- a/sys/boot/fdt/fdt_loader_cmd.c
+++ b/sys/boot/fdt/fdt_loader_cmd.c
@@ -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 *header)
{
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,41 +254,103 @@ fdt_load_dtb_addr(struct fdt_header *header)
}
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;
- struct fdt_header *hdr;
- const char *s;
- char *p;
- vm_offset_t va;
-
- if ((bfp = file_findfile(NULL, "dtb")) != NULL) {
- printf("Using DTB from loaded file.\n");
- return fdt_load_dtb(bfp->f_addr);
- }
-
- 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);
- }
-
- s = ub_env_get("fdtaddr");
- 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 ((va = fdt_find_static_dtb()) != 0) {
- printf("Using DTB compiled into kernel.\n");
- return (fdt_load_dtb(va));
- }
-
- command_errmsg = "no device tree blob found!";
- return (1);
+ struct preloaded_file *bfp;
+ struct fdt_header *hdr;
+ 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) {
+ 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) {
+ 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);
+ }
+ }
+
+ /*
+ * 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') {
+ 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) {
+ if (fdt_load_dtb(va) == 0) {
+ printf("Using DTB compiled into kernel.\n");
+ return (0);
+ }
+ }
+
+ command_errmsg = "No device tree blob found!\n";
+ return (1);
}
#define fdt_strtovect(str, cellbuf, lim, cellsize) _fdt_strtovect((str), \
@@ -675,6 +743,8 @@ fdt_fixup(void)
ethstr = NULL;
len = 0;
+ debugf("fdt_fixup()\n");
+
if (fdtp == NULL && fdt_setup_fdtp() != 0)
return (0);
@@ -738,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) {
OpenPOWER on IntegriCloud