Changeset View
Changeset View
Standalone View
Standalone View
head/stand/fdt/fdt_loader_cmd.c
Show First 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | |||||
/* Size of FDT blob */ | /* Size of FDT blob */ | ||||
static size_t fdtp_size = 0; | static size_t fdtp_size = 0; | ||||
/* Location of FDT in kernel or module. */ | /* Location of FDT in kernel or module. */ | ||||
/* This won't be set if FDT is loaded from disk or memory. */ | /* This won't be set if FDT is loaded from disk or memory. */ | ||||
/* If it is set, we'll update it when fdt_copy() gets called. */ | /* If it is set, we'll update it when fdt_copy() gets called. */ | ||||
static vm_offset_t fdtp_va = 0; | static vm_offset_t fdtp_va = 0; | ||||
static int fdt_load_dtb(vm_offset_t va); | static int fdt_load_dtb(vm_offset_t va); | ||||
static void fdt_print_overlay_load_error(int err, const char *filename); | |||||
static int fdt_cmd_nyi(int argc, char *argv[]); | static int fdt_cmd_nyi(int argc, char *argv[]); | ||||
static int fdt_cmd_addr(int argc, char *argv[]); | static int fdt_cmd_addr(int argc, char *argv[]); | ||||
static int fdt_cmd_mkprop(int argc, char *argv[]); | static int fdt_cmd_mkprop(int argc, char *argv[]); | ||||
static int fdt_cmd_cd(int argc, char *argv[]); | static int fdt_cmd_cd(int argc, char *argv[]); | ||||
static int fdt_cmd_hdr(int argc, char *argv[]); | static int fdt_cmd_hdr(int argc, char *argv[]); | ||||
static int fdt_cmd_ls(int argc, char *argv[]); | static int fdt_cmd_ls(int argc, char *argv[]); | ||||
▲ Show 20 Lines • Show All 197 Lines • ▼ Show 20 Lines | |||||
fdt_load_dtb_overlay(const char * filename) | fdt_load_dtb_overlay(const char * filename) | ||||
{ | { | ||||
struct preloaded_file *bfp; | struct preloaded_file *bfp; | ||||
struct fdt_header header; | struct fdt_header header; | ||||
int err; | int err; | ||||
debugf("fdt_load_dtb_overlay(%s)\n", filename); | debugf("fdt_load_dtb_overlay(%s)\n", filename); | ||||
/* Attempt to load and validate a new dtb from a file. */ | /* Attempt to load and validate a new dtb from a file. FDT_ERR_NOTFOUND | ||||
if ((bfp = file_loadraw(filename, "dtbo", 1)) == NULL) { | * is normally a libfdt error code, but libfdt would actually return | ||||
printf("failed to load file '%s'\n", filename); | * -FDT_ERR_NOTFOUND. We re-purpose the error code here to convey a | ||||
return (1); | * similar meaning: the file itself was not found, which can still be | ||||
} | * considered an error dealing with FDT pieces. | ||||
*/ | |||||
if ((bfp = file_loadraw(filename, "dtbo", 1)) == NULL) | |||||
return (FDT_ERR_NOTFOUND); | |||||
COPYOUT(bfp->f_addr, &header, sizeof(header)); | COPYOUT(bfp->f_addr, &header, sizeof(header)); | ||||
err = fdt_check_header(&header); | err = fdt_check_header(&header); | ||||
if (err < 0) { | if (err < 0) { | ||||
file_discard(bfp); | file_discard(bfp); | ||||
if (err == -FDT_ERR_BADVERSION) | return (err); | ||||
printf("incompatible blob version: %d, should be: %d\n", | |||||
fdt_version(fdtp), FDT_LAST_SUPPORTED_VERSION); | |||||
else | |||||
printf("error validating blob: %s\n", | |||||
fdt_strerror(err)); | |||||
return (1); | |||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | |||||
fdt_print_overlay_load_error(int err, const char *filename) | |||||
{ | |||||
switch (err) { | |||||
case FDT_ERR_NOTFOUND: | |||||
printf("%s: failed to load file\n", filename); | |||||
break; | |||||
case -FDT_ERR_BADVERSION: | |||||
printf("%s: incompatible blob version: %d, should be: %d\n", | |||||
filename, fdt_version(fdtp), | |||||
FDT_LAST_SUPPORTED_VERSION); | |||||
break; | |||||
default: | |||||
/* libfdt errs are negative */ | |||||
if (err < 0) | |||||
printf("%s: error validating blob: %s\n", | |||||
filename, fdt_strerror(err)); | |||||
else | |||||
printf("%s: unknown load error\n", filename); | |||||
break; | |||||
} | |||||
} | |||||
int | int | ||||
fdt_load_dtb_overlays(const char * filenames) | fdt_load_dtb_overlays(const char * filenames) | ||||
{ | { | ||||
char *names; | char *names; | ||||
char *name; | char *name, *name_ext; | ||||
char *comaptr; | char *comaptr; | ||||
int err, namesz; | |||||
debugf("fdt_load_dtb_overlay(%s)\n", filenames); | debugf("fdt_load_dtb_overlay(%s)\n", filenames); | ||||
names = strdup(filenames); | names = strdup(filenames); | ||||
if (names == NULL) | if (names == NULL) | ||||
return (1); | return (1); | ||||
name = names; | name = names; | ||||
do { | do { | ||||
comaptr = strchr(name, ','); | comaptr = strchr(name, ','); | ||||
if (comaptr) | if (comaptr) | ||||
*comaptr = '\0'; | *comaptr = '\0'; | ||||
fdt_load_dtb_overlay(name); | err = fdt_load_dtb_overlay(name); | ||||
if (err == FDT_ERR_NOTFOUND) { | |||||
/* Allocate enough to append ".dtbo" */ | |||||
namesz = strlen(name) + 6; | |||||
name_ext = malloc(namesz); | |||||
if (name_ext == NULL) { | |||||
fdt_print_overlay_load_error(err, name); | |||||
name = comaptr + 1; | |||||
continue; | |||||
} | |||||
snprintf(name_ext, namesz, "%s.dtbo", name); | |||||
err = fdt_load_dtb_overlay(name_ext); | |||||
free(name_ext); | |||||
} | |||||
/* Catch error with either initial load or fallback load */ | |||||
if (err != 0) | |||||
fdt_print_overlay_load_error(err, name); | |||||
name = comaptr + 1; | name = comaptr + 1; | ||||
} while(comaptr); | } while(comaptr); | ||||
free(names); | free(names); | ||||
return (0); | return (0); | ||||
} | } | ||||
void | void | ||||
▲ Show 20 Lines • Show All 1,402 Lines • Show Last 20 Lines |