Page MenuHomeFreeBSD

D13969.diff
No OneTemporary

D13969.diff

Index: head/stand/fdt/fdt_loader_cmd.c
===================================================================
--- head/stand/fdt/fdt_loader_cmd.c
+++ head/stand/fdt/fdt_loader_cmd.c
@@ -74,6 +74,7 @@
static int fdt_load_dtb(vm_offset_t va);
static void fdt_print_overlay_load_error(int err, const char *filename);
+static int fdt_check_overlay_compatible(void *base_fdt, void *overlay_fdt);
static int fdt_cmd_nyi(int argc, char *argv[]);
static int fdt_load_dtb_overlays_string(const char * filenames);
@@ -374,6 +375,62 @@
return (0);
}
+/*
+ * fdt_check_overlay_compatible - check that the overlay_fdt is compatible with
+ * base_fdt before we attempt to apply it. It will need to re-calculate offsets
+ * in the base every time, rather than trying to cache them earlier in the
+ * process, because the overlay application process can/will invalidate a lot of
+ * offsets.
+ */
+static int
+fdt_check_overlay_compatible(void *base_fdt, void *overlay_fdt)
+{
+ const char *compat;
+ int compat_len, ocompat_len;
+ int oroot_offset, root_offset;
+ int slidx, sllen;
+
+ oroot_offset = fdt_path_offset(overlay_fdt, "/");
+ if (oroot_offset < 0)
+ return (oroot_offset);
+ /*
+ * If /compatible in the overlay does not exist or if it is empty, then
+ * we're automatically compatible. We do this for the sake of rapid
+ * overlay development for overlays that aren't intended to be deployed.
+ * The user assumes the risk of using an overlay without /compatible.
+ */
+ if (fdt_get_property(overlay_fdt, oroot_offset, "compatible",
+ &ocompat_len) == NULL || ocompat_len == 0)
+ return (0);
+ root_offset = fdt_path_offset(base_fdt, "/");
+ if (root_offset < 0)
+ return (root_offset);
+ /*
+ * However, an empty or missing /compatible on the base is an error,
+ * because allowing this offers no advantages.
+ */
+ if (fdt_get_property(base_fdt, root_offset, "compatible",
+ &compat_len) == NULL)
+ return (compat_len);
+ else if(compat_len == 0)
+ return (1);
+
+ slidx = 0;
+ compat = fdt_stringlist_get(overlay_fdt, oroot_offset, "compatible",
+ slidx, &sllen);
+ while (compat != NULL) {
+ if (fdt_stringlist_search(base_fdt, root_offset, "compatible",
+ compat) >= 0)
+ return (0);
+ ++slidx;
+ compat = fdt_stringlist_get(overlay_fdt, oroot_offset,
+ "compatible", slidx, &sllen);
+ };
+
+ /* We've exhausted the overlay's /compatible property... no match */
+ return (1);
+}
+
void
fdt_apply_overlays()
{
@@ -408,6 +465,13 @@
current_fdtp = fdtp;
current_fdtp_size = fdtp_size;
for (fp = file_findfile(NULL, "dtbo"); fp != NULL; fp = fp->f_next) {
+ COPYOUT(fp->f_addr, overlay, fp->f_size);
+ /* Check compatible first to avoid unnecessary allocation */
+ rv = fdt_check_overlay_compatible(current_fdtp, overlay);
+ if (rv != 0) {
+ printf("DTB overlay '%s' not compatible\n", fp->f_name);
+ continue;
+ }
printf("applying DTB overlay '%s'\n", fp->f_name);
next_fdtp_size = current_fdtp_size + fp->f_size;
next_fdtp = malloc(next_fdtp_size);
@@ -425,7 +489,6 @@
printf("failed to open base dtb into overlay base\n");
continue;
}
- COPYOUT(fp->f_addr, overlay, fp->f_size);
/* Both overlay and new_fdtp may be modified in place */
rv = fdt_overlay_apply(next_fdtp, overlay);
if (rv == 0) {

File Metadata

Mime Type
text/plain
Expires
Sun, Jul 26, 11:58 PM (15 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35578596
Default Alt Text
D13969.diff (3 KB)

Event Timeline