Changeset View
Changeset View
Standalone View
Standalone View
head/stand/fdt/fdt_loader_cmd.c
Show First 20 Lines • Show All 334 Lines • ▼ Show 20 Lines | fdt_load_dtb_overlays(const char * filenames) | ||||
free(names); | free(names); | ||||
return (0); | return (0); | ||||
} | } | ||||
void | void | ||||
fdt_apply_overlays() | fdt_apply_overlays() | ||||
{ | { | ||||
struct preloaded_file *fp; | struct preloaded_file *fp; | ||||
size_t overlays_size, max_overlay_size, new_fdtp_size; | size_t max_overlay_size, next_fdtp_size; | ||||
size_t current_fdtp_size; | |||||
void *current_fdtp; | |||||
void *new_fdtp; | void *new_fdtp; | ||||
void *next_fdtp; | |||||
void *overlay; | void *overlay; | ||||
int rv; | int rv; | ||||
if ((fdtp == NULL) || (fdtp_size == 0)) | if ((fdtp == NULL) || (fdtp_size == 0)) | ||||
return; | return; | ||||
overlays_size = 0; | new_fdtp = NULL; | ||||
max_overlay_size = 0; | max_overlay_size = 0; | ||||
for (fp = file_findfile(NULL, "dtbo"); fp != NULL; fp = fp->f_next) { | for (fp = file_findfile(NULL, "dtbo"); fp != NULL; fp = fp->f_next) { | ||||
if (max_overlay_size < fp->f_size) | if (max_overlay_size < fp->f_size) | ||||
max_overlay_size = fp->f_size; | max_overlay_size = fp->f_size; | ||||
overlays_size += fp->f_size; | |||||
} | } | ||||
/* Nothing to apply */ | /* Nothing to apply */ | ||||
if (overlays_size == 0) | if (max_overlay_size == 0) | ||||
return; | return; | ||||
/* It's actually more than enough */ | |||||
new_fdtp_size = fdtp_size + overlays_size; | |||||
new_fdtp = malloc(new_fdtp_size); | |||||
if (new_fdtp == NULL) { | |||||
printf("failed to allocate memory for DTB blob with overlays\n"); | |||||
return; | |||||
} | |||||
overlay = malloc(max_overlay_size); | overlay = malloc(max_overlay_size); | ||||
if (overlay == NULL) { | if (overlay == NULL) { | ||||
printf("failed to allocate memory for DTB blob with overlays\n"); | printf("failed to allocate memory for DTB blob with overlays\n"); | ||||
free(new_fdtp); | |||||
return; | return; | ||||
} | } | ||||
current_fdtp = fdtp; | |||||
rv = fdt_open_into(fdtp, new_fdtp, new_fdtp_size); | current_fdtp_size = fdtp_size; | ||||
if (rv != 0) { | |||||
printf("failed to open DTB blob for applying overlays\n"); | |||||
free(new_fdtp); | |||||
free(overlay); | |||||
return; | |||||
} | |||||
for (fp = file_findfile(NULL, "dtbo"); fp != NULL; fp = fp->f_next) { | for (fp = file_findfile(NULL, "dtbo"); fp != NULL; fp = fp->f_next) { | ||||
printf("applying DTB overlay '%s'\n", fp->f_name); | printf("applying DTB overlay '%s'\n", fp->f_name); | ||||
next_fdtp_size = current_fdtp_size + fp->f_size; | |||||
next_fdtp = malloc(next_fdtp_size); | |||||
if (next_fdtp == NULL) { | |||||
/* | |||||
* Output warning, then move on to applying other | |||||
* overlays in case this one is simply too large. | |||||
*/ | |||||
printf("failed to allocate memory for overlay base\n"); | |||||
continue; | |||||
} | |||||
rv = fdt_open_into(current_fdtp, next_fdtp, next_fdtp_size); | |||||
if (rv != 0) { | |||||
printf("failed to open base dtb into overlay base\n"); | |||||
continue; | |||||
} | |||||
COPYOUT(fp->f_addr, overlay, fp->f_size); | COPYOUT(fp->f_addr, overlay, fp->f_size); | ||||
/* Both overlay and new_fdtp may be modified in place */ | /* Both overlay and new_fdtp may be modified in place */ | ||||
fdt_overlay_apply(new_fdtp, overlay); | rv = fdt_overlay_apply(next_fdtp, overlay); | ||||
if (rv == 0) { | |||||
/* Rotate next -> current */ | |||||
if (current_fdtp != fdtp) | |||||
free(current_fdtp); | |||||
current_fdtp = next_fdtp; | |||||
current_fdtp_size = next_fdtp_size; | |||||
} else { | |||||
/* | |||||
* Assume here that the base we tried to apply on is | |||||
* either trashed or in an inconsistent state. Trying to | |||||
* load it might work, but it's better to discard it and | |||||
* play it safe. */ | |||||
free(next_fdtp); | |||||
printf("failed to apply overlay: %s\n", | |||||
fdt_strerror(rv)); | |||||
} | } | ||||
} | |||||
/* We could have failed to apply all overlays; then we do nothing */ | |||||
if (current_fdtp != fdtp) { | |||||
free(fdtp); | free(fdtp); | ||||
fdtp = new_fdtp; | fdtp = current_fdtp; | ||||
fdtp_size = new_fdtp_size; | fdtp_size = current_fdtp_size; | ||||
} | |||||
free(overlay); | free(overlay); | ||||
} | } | ||||
int | int | ||||
fdt_setup_fdtp() | fdt_setup_fdtp() | ||||
{ | { | ||||
struct preloaded_file *bfp; | struct preloaded_file *bfp; | ||||
vm_offset_t va; | vm_offset_t va; | ||||
▲ Show 20 Lines • Show All 1,318 Lines • Show Last 20 Lines |