<p>Patrick Rudolph has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/25739">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">lib: Raw import FIT parser<br><br>Import from https://chromium.googlesource.com/chromiumos/platform/depthcharge<br><br>Coding style and coreboot integration will be done in a separate commit.<br><br>Change-Id: Iee56db328d7eeffb0eaf829841243b0b9195c199<br>Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com><br>---<br>A src/include/fit.h<br>A src/lib/fit.c<br>2 files changed, 566 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/39/25739/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/include/fit.h b/src/include/fit.h</span><br><span>new file mode 100644</span><br><span>index 0000000..1b2f975</span><br><span>--- /dev/null</span><br><span>+++ b/src/include/fit.h</span><br><span>@@ -0,0 +1,78 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2013 Google Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See file CREDITS for list of people who contributed to this</span><br><span style="color: hsl(120, 100%, 40%);">+ * project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or</span><br><span style="color: hsl(120, 100%, 40%);">+ * modify it under the terms of the GNU General Public License as</span><br><span style="color: hsl(120, 100%, 40%);">+ * published by the Free Software Foundation; either version 2 of</span><br><span style="color: hsl(120, 100%, 40%);">+ * the License, or (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but without any warranty; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef __BOOT_FIT_H__</span><br><span style="color: hsl(120, 100%, 40%);">+#define __BOOT_FIT_H__</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stddef.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "base/device_tree.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "base/list.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+typedef enum CompressionType</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   CompressionInvalid,</span><br><span style="color: hsl(120, 100%, 40%);">+   CompressionNone,</span><br><span style="color: hsl(120, 100%, 40%);">+      CompressionLzma,</span><br><span style="color: hsl(120, 100%, 40%);">+      CompressionLz4,</span><br><span style="color: hsl(120, 100%, 40%);">+} CompressionType;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+typedef struct FitImageNode</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *name;</span><br><span style="color: hsl(120, 100%, 40%);">+     void *data;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint32_t size;</span><br><span style="color: hsl(120, 100%, 40%);">+        CompressionType compression;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        ListNode list_node;</span><br><span style="color: hsl(120, 100%, 40%);">+} FitImageNode;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+typedef struct FitConfigNode</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *name;</span><br><span style="color: hsl(120, 100%, 40%);">+     const char *kernel;</span><br><span style="color: hsl(120, 100%, 40%);">+   FitImageNode *kernel_node;</span><br><span style="color: hsl(120, 100%, 40%);">+    const char *fdt;</span><br><span style="color: hsl(120, 100%, 40%);">+      FitImageNode *fdt_node;</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *ramdisk;</span><br><span style="color: hsl(120, 100%, 40%);">+  FitImageNode *ramdisk_node;</span><br><span style="color: hsl(120, 100%, 40%);">+   FdtProperty compat;</span><br><span style="color: hsl(120, 100%, 40%);">+   int compat_rank;</span><br><span style="color: hsl(120, 100%, 40%);">+      int compat_pos;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ListNode list_node;</span><br><span style="color: hsl(120, 100%, 40%);">+} FitConfigNode;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Unpack a FIT image into memory, choosing the right configuration through the</span><br><span style="color: hsl(120, 100%, 40%);">+ * compatible string set by fit_add_compat() and unflattening the corresponding</span><br><span style="color: hsl(120, 100%, 40%);">+ * kernel device tree.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+FitImageNode *fit_load(void *fit, char *cmd_line, DeviceTree **dt);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Add a compatible string for the preferred kernel DT to the list for this</span><br><span style="color: hsl(120, 100%, 40%);">+ * platform. This should be called before the first fit_load() so it will be</span><br><span style="color: hsl(120, 100%, 40%);">+ * ranked as a better match than the default compatible strings. |compat| must</span><br><span style="color: hsl(120, 100%, 40%);">+ * stay accessible throughout depthcharge's runtime (i.e. not stack-allocated)!</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void fit_add_compat(const char *compat);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void fit_add_ramdisk(DeviceTree *tree, void *ramdisk_addr, size_t ramdisk_size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif /* __BOOT_FIT_H__ */</span><br><span>diff --git a/src/lib/fit.c b/src/lib/fit.c</span><br><span>new file mode 100644</span><br><span>index 0000000..6390431</span><br><span>--- /dev/null</span><br><span>+++ b/src/lib/fit.c</span><br><span>@@ -0,0 +1,488 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2013 Google Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See file CREDITS for list of people who contributed to this</span><br><span style="color: hsl(120, 100%, 40%);">+ * project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or</span><br><span style="color: hsl(120, 100%, 40%);">+ * modify it under the terms of the GNU General Public License as</span><br><span style="color: hsl(120, 100%, 40%);">+ * published by the Free Software Foundation; either version 2 of</span><br><span style="color: hsl(120, 100%, 40%);">+ * the License, or (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <assert.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <endian.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <libpayload.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "base/ranges.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "boot/fit.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "config.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static ListNode image_nodes;</span><br><span style="color: hsl(120, 100%, 40%);">+static ListNode config_nodes;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *fit_kernel_compat[10] = { NULL };</span><br><span style="color: hsl(120, 100%, 40%);">+static int num_fit_kernel_compat = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void fit_add_compat(const char *compat)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     assert(num_fit_kernel_compat < ARRAY_SIZE(fit_kernel_compat));</span><br><span style="color: hsl(120, 100%, 40%);">+     fit_kernel_compat[num_fit_kernel_compat++] = compat;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void fit_add_default_compats(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       const char pattern[] = "google,%s-rev%u-sku%u";</span><br><span style="color: hsl(120, 100%, 40%);">+     u32 rev = lib_sysinfo.board_id;</span><br><span style="color: hsl(120, 100%, 40%);">+       u32 sku = lib_sysinfo.sku_id;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       static int done = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  if (done)</span><br><span style="color: hsl(120, 100%, 40%);">+             return;</span><br><span style="color: hsl(120, 100%, 40%);">+       done = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   char *compat = xmalloc(sizeof(pattern) + sizeof(CONFIG_BOARD) + 20);</span><br><span style="color: hsl(120, 100%, 40%);">+  sprintf(compat, pattern, CONFIG_BOARD,</span><br><span style="color: hsl(120, 100%, 40%);">+                lib_sysinfo.board_id, lib_sysinfo.sku_id);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  char *c;</span><br><span style="color: hsl(120, 100%, 40%);">+      for (c = compat; *c != '\0'; c++)</span><br><span style="color: hsl(120, 100%, 40%);">+             if (*c == '_')</span><br><span style="color: hsl(120, 100%, 40%);">+                        *c = '-';</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (sku != UNDEFINED_STRAPPING_ID && rev != UNDEFINED_STRAPPING_ID)</span><br><span style="color: hsl(120, 100%, 40%);">+           fit_add_compat(strdup(compat));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     *strrchr(compat, '-') = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rev != UNDEFINED_STRAPPING_ID)</span><br><span style="color: hsl(120, 100%, 40%);">+            fit_add_compat(strdup(compat));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     *strrchr(compat, '-') = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+ fit_add_compat(compat);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void image_node(DeviceTreeNode *node)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   FitImageNode *image = xzalloc(sizeof(*image));</span><br><span style="color: hsl(120, 100%, 40%);">+        image->compression = CompressionNone;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    image->name = node->name;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     DeviceTreeProperty *prop;</span><br><span style="color: hsl(120, 100%, 40%);">+     list_for_each(prop, node->properties, list_node) {</span><br><span style="color: hsl(120, 100%, 40%);">+         if (!strcmp("data", prop->prop.name)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  image->data = prop->prop.data;</span><br><span style="color: hsl(120, 100%, 40%);">+                  image->size = prop->prop.size;</span><br><span style="color: hsl(120, 100%, 40%);">+          } else if (!strcmp("compression", prop->prop.name)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (!strcmp("none", prop->prop.data))</span><br><span style="color: hsl(120, 100%, 40%);">+                            image->compression = CompressionNone;</span><br><span style="color: hsl(120, 100%, 40%);">+                      else if (!strcmp("lzma", prop->prop.data))</span><br><span style="color: hsl(120, 100%, 40%);">+                               image->compression = CompressionLzma;</span><br><span style="color: hsl(120, 100%, 40%);">+                      else if (!strcmp("lz4", prop->prop.data))</span><br><span style="color: hsl(120, 100%, 40%);">+                                image->compression = CompressionLz4;</span><br><span style="color: hsl(120, 100%, 40%);">+                       else</span><br><span style="color: hsl(120, 100%, 40%);">+                          image->compression = CompressionInvalid;</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   list_insert_after(&image->list_node, &image_nodes);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void config_node(DeviceTreeNode *node)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ FitConfigNode *config = xzalloc(sizeof(*config));</span><br><span style="color: hsl(120, 100%, 40%);">+     config->name = node->name;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    DeviceTreeProperty *prop;</span><br><span style="color: hsl(120, 100%, 40%);">+     list_for_each(prop, node->properties, list_node) {</span><br><span style="color: hsl(120, 100%, 40%);">+         if (!strcmp("kernel", prop->prop.name))</span><br><span style="color: hsl(120, 100%, 40%);">+                  config->kernel = prop->prop.data;</span><br><span style="color: hsl(120, 100%, 40%);">+               else if (!strcmp("fdt", prop->prop.name))</span><br><span style="color: hsl(120, 100%, 40%);">+                        config->fdt = prop->prop.data;</span><br><span style="color: hsl(120, 100%, 40%);">+          else if (!strcmp("ramdisk", prop->prop.name))</span><br><span style="color: hsl(120, 100%, 40%);">+                    config->ramdisk = prop->prop.data;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   list_insert_after(&config->list_node, &config_nodes);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void fit_unpack(DeviceTree *tree, const char **default_config)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       assert(tree && tree->root);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      DeviceTreeNode *top;</span><br><span style="color: hsl(120, 100%, 40%);">+  list_for_each(top, tree->root->children, list_node) {</span><br><span style="color: hsl(120, 100%, 40%);">+           DeviceTreeNode *child;</span><br><span style="color: hsl(120, 100%, 40%);">+                if (!strcmp("images", top->name)) {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                    list_for_each(child, top->children, list_node)</span><br><span style="color: hsl(120, 100%, 40%);">+                             image_node(child);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          } else if (!strcmp("configurations", top->name)) {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                     DeviceTreeProperty *prop;</span><br><span style="color: hsl(120, 100%, 40%);">+                     list_for_each(prop, top->properties, list_node) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          if (!strcmp("default", prop->prop.name) &&</span><br><span style="color: hsl(120, 100%, 40%);">+                                               default_config)</span><br><span style="color: hsl(120, 100%, 40%);">+                                       *default_config = prop->prop.data;</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   list_for_each(child, top->children, list_node)</span><br><span style="color: hsl(120, 100%, 40%);">+                             config_node(child);</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static FitImageNode *find_image(const char *name)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  FitImageNode *image;</span><br><span style="color: hsl(120, 100%, 40%);">+  list_for_each(image, image_nodes, list_node) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (!strcmp(image->name, name))</span><br><span style="color: hsl(120, 100%, 40%);">+                    return image;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+     return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int fdt_find_compat(void *blob, uint32_t start_offset, FdtProperty *prop)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        int offset = start_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+    int size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   size = fdt_node_name(blob, offset, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!size)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    offset += size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     while ((size = fdt_next_property(blob, offset, prop))) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (!strcmp("compatible", prop->name))</span><br><span style="color: hsl(120, 100%, 40%);">+                   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           offset += size;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   prop->name = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int fit_check_compat(FdtProperty *compat_prop, const char *compat_name)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    int bytes = compat_prop->size;</span><br><span style="color: hsl(120, 100%, 40%);">+     const char *compat_str = compat_prop->data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      for (int pos = 0; bytes && compat_str[0]; pos++) {</span><br><span style="color: hsl(120, 100%, 40%);">+            if (!strncmp(compat_str, compat_name, bytes))</span><br><span style="color: hsl(120, 100%, 40%);">+                 return pos;</span><br><span style="color: hsl(120, 100%, 40%);">+           int len = strlen(compat_str) + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+             compat_str += len;</span><br><span style="color: hsl(120, 100%, 40%);">+            bytes -= len;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+     return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void update_chosen(DeviceTree *tree, char *cmd_line)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *path[] = { "chosen", NULL };</span><br><span style="color: hsl(120, 100%, 40%);">+    DeviceTreeNode *node = dt_find_node(tree->root, path, NULL, NULL, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    dt_add_string_prop(node, "bootargs", cmd_line);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void fit_add_ramdisk(DeviceTree *tree, void *ramdisk_addr, size_t ramdisk_size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    const char *path[] = { "chosen", NULL };</span><br><span style="color: hsl(120, 100%, 40%);">+    DeviceTreeNode *node = dt_find_node(tree->root, path, NULL, NULL, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Warning: this assumes the ramdisk is currently located below 4GiB. */</span><br><span style="color: hsl(120, 100%, 40%);">+      u32 start = (uintptr_t)ramdisk_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+  u32 end = start + ramdisk_size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     dt_add_u32_prop(node, "linux,initrd-start", start);</span><br><span style="color: hsl(120, 100%, 40%);">+ dt_add_u32_prop(node, "linux,initrd-end", end);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void update_reserve_map(uint64_t start, uint64_t end, void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   DeviceTree *tree = (DeviceTree *)data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      DeviceTreeReserveMapEntry *entry = xzalloc(sizeof(*entry));</span><br><span style="color: hsl(120, 100%, 40%);">+   entry->start = start;</span><br><span style="color: hsl(120, 100%, 40%);">+      entry->size = end - start;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       list_insert_after(&entry->list_node, &tree->reserve_map);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+typedef struct EntryParams</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned addr_cells;</span><br><span style="color: hsl(120, 100%, 40%);">+  unsigned size_cells;</span><br><span style="color: hsl(120, 100%, 40%);">+  void *data;</span><br><span style="color: hsl(120, 100%, 40%);">+} EntryParams;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static uint64_t max_range(unsigned size_cells)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      // Split up ranges who's sizes are too large to fit in #size-cells.</span><br><span style="color: hsl(120, 100%, 40%);">+       // The largest value we can store isn't a power of two, so we'll round</span><br><span style="color: hsl(120, 100%, 40%);">+        // down to make the math easier.</span><br><span style="color: hsl(120, 100%, 40%);">+      return 0x1ULL << (size_cells * 32 - 1);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void count_entries(u64 start, u64 end, void *pdata)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     EntryParams *params = (EntryParams *)pdata;</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned *count = (unsigned *)params->data;</span><br><span style="color: hsl(120, 100%, 40%);">+        u64 size = end - start;</span><br><span style="color: hsl(120, 100%, 40%);">+       u64 max_size = max_range(params->size_cells);</span><br><span style="color: hsl(120, 100%, 40%);">+      *count += ALIGN_UP(size, max_size) / max_size;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void update_mem_property(u64 start, u64 end, void *pdata)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      EntryParams *params = (EntryParams *)pdata;</span><br><span style="color: hsl(120, 100%, 40%);">+   u8 *data = (u8 *)params->data;</span><br><span style="color: hsl(120, 100%, 40%);">+     u64 full_size = end - start;</span><br><span style="color: hsl(120, 100%, 40%);">+  while (full_size) {</span><br><span style="color: hsl(120, 100%, 40%);">+           const u64 max_size = max_range(params->size_cells);</span><br><span style="color: hsl(120, 100%, 40%);">+                const u32 size = MIN(max_size, full_size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          dt_write_int(data, start, params->addr_cells * sizeof(u32));</span><br><span style="color: hsl(120, 100%, 40%);">+               data += params->addr_cells * sizeof(uint32_t);</span><br><span style="color: hsl(120, 100%, 40%);">+             start += size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              dt_write_int(data, size, params->size_cells * sizeof(u32));</span><br><span style="color: hsl(120, 100%, 40%);">+                data += params->size_cells * sizeof(uint32_t);</span><br><span style="color: hsl(120, 100%, 40%);">+             full_size -= size;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     params->data = data;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void update_memory(DeviceTree *tree)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  Ranges mem;</span><br><span style="color: hsl(120, 100%, 40%);">+   Ranges reserved;</span><br><span style="color: hsl(120, 100%, 40%);">+      DeviceTreeNode *node;</span><br><span style="color: hsl(120, 100%, 40%);">+ u32 addr_cells = 1, size_cells = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+   dt_read_cell_props(tree->root, &addr_cells, &size_cells);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        // First remove all existing device_type="memory" nodes, then add ours.</span><br><span style="color: hsl(120, 100%, 40%);">+     list_for_each(node, tree->root->children, list_node) {</span><br><span style="color: hsl(120, 100%, 40%);">+          const char *devtype = dt_find_string_prop(node, "device_type");</span><br><span style="color: hsl(120, 100%, 40%);">+             if (devtype && !strcmp(devtype, "memory"))</span><br><span style="color: hsl(120, 100%, 40%);">+                  list_remove(&node->list_node);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+     node = xzalloc(sizeof(*node));</span><br><span style="color: hsl(120, 100%, 40%);">+        node->name = "memory";</span><br><span style="color: hsl(120, 100%, 40%);">+   list_insert_after(&node->list_node, &tree->root->children);</span><br><span style="color: hsl(120, 100%, 40%);">+  dt_add_string_prop(node, "device_type", "memory");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      // Read memory info from coreboot (ranges are merged automatically).</span><br><span style="color: hsl(120, 100%, 40%);">+  ranges_init(&mem);</span><br><span style="color: hsl(120, 100%, 40%);">+        ranges_init(&reserved);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define MEMORY_ALIGNMENT (1 << 20)</span><br><span style="color: hsl(120, 100%, 40%);">+       for (int i = 0; i < lib_sysinfo.n_memranges; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                struct memrange *range = &lib_sysinfo.memrange[i];</span><br><span style="color: hsl(120, 100%, 40%);">+                uint64_t start = range->base;</span><br><span style="color: hsl(120, 100%, 40%);">+              uint64_t end = range->base + range->size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             /*</span><br><span style="color: hsl(120, 100%, 40%);">+             * Kernel likes its availabe memory areas at least 1MB</span><br><span style="color: hsl(120, 100%, 40%);">+                 * aligned, let's trim the regions such that unaligned padding</span><br><span style="color: hsl(120, 100%, 40%);">+             * is added to reserved memory.</span><br><span style="color: hsl(120, 100%, 40%);">+                */</span><br><span style="color: hsl(120, 100%, 40%);">+           if (range->type == CB_MEM_RAM) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   uint64_t new_start = ALIGN_UP(start, MEMORY_ALIGNMENT);</span><br><span style="color: hsl(120, 100%, 40%);">+                       uint64_t new_end = ALIGN_DOWN(end, MEMORY_ALIGNMENT);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (new_start != start)</span><br><span style="color: hsl(120, 100%, 40%);">+                               ranges_add(&reserved, start, new_start);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                        if (new_start != new_end)</span><br><span style="color: hsl(120, 100%, 40%);">+                             ranges_add(&mem, new_start, new_end);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (new_end != end)</span><br><span style="color: hsl(120, 100%, 40%);">+                           ranges_add(&reserved, new_end, end);</span><br><span style="color: hsl(120, 100%, 40%);">+              } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      ranges_add(&reserved, start, end);</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   // CBMEM regions are both carved out and explicitly reserved.</span><br><span style="color: hsl(120, 100%, 40%);">+ ranges_for_each(&reserved, &update_reserve_map, tree);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      // Count the amount of 'reg' entries we need (account for size limits).</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned count = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   EntryParams count_params = { addr_cells, size_cells, &count };</span><br><span style="color: hsl(120, 100%, 40%);">+    ranges_for_each(&mem, &count_entries, &count_params);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   // Allocate the right amount of space and fill up the entries.</span><br><span style="color: hsl(120, 100%, 40%);">+        size_t length = count * (addr_cells + size_cells) * sizeof(u32);</span><br><span style="color: hsl(120, 100%, 40%);">+      void *data = xmalloc(length);</span><br><span style="color: hsl(120, 100%, 40%);">+ EntryParams add_params = { addr_cells, size_cells, data };</span><br><span style="color: hsl(120, 100%, 40%);">+    ranges_for_each(&mem, &update_mem_property, &add_params);</span><br><span style="color: hsl(120, 100%, 40%);">+ assert(add_params.data - data == length);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   // Assemble the final property and add it to the device tree.</span><br><span style="color: hsl(120, 100%, 40%);">+ dt_add_bin_prop(node, "reg", data, length);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+FitImageNode *fit_load(void *fit, char *cmd_line, DeviceTree **dt)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     FdtHeader *header = (FdtHeader *)fit;</span><br><span style="color: hsl(120, 100%, 40%);">+ FitImageNode *image;</span><br><span style="color: hsl(120, 100%, 40%);">+  FitConfigNode *config;</span><br><span style="color: hsl(120, 100%, 40%);">+        int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      printf("Loading FIT.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (betohl(header->magic) != FdtMagic) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printf("Bad FIT header magic value 0x%08x.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                      betohl(header->magic));</span><br><span style="color: hsl(120, 100%, 40%);">+            return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   DeviceTree *tree = fdt_unflatten(fit);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      const char *default_config_name = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+       FitConfigNode *default_config = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ FitConfigNode *compat_config = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        fit_unpack(tree, &default_config_name);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ // List the images we found.</span><br><span style="color: hsl(120, 100%, 40%);">+  list_for_each(image, image_nodes, list_node)</span><br><span style="color: hsl(120, 100%, 40%);">+          printf("Image %s has %d bytes.\n", image->name, image->size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       fit_add_default_compats();</span><br><span style="color: hsl(120, 100%, 40%);">+    printf("Compat preference:");</span><br><span style="color: hsl(120, 100%, 40%);">+       for (i = 0; i < num_fit_kernel_compat; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+                printf(" %s", fit_kernel_compat[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       // Process and list the configs.</span><br><span style="color: hsl(120, 100%, 40%);">+      list_for_each(config, config_nodes, list_node) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (config->kernel)</span><br><span style="color: hsl(120, 100%, 40%);">+                        config->kernel_node = find_image(config->kernel);</span><br><span style="color: hsl(120, 100%, 40%);">+               if (config->fdt)</span><br><span style="color: hsl(120, 100%, 40%);">+                   config->fdt_node = find_image(config->fdt);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (config->ramdisk)</span><br><span style="color: hsl(120, 100%, 40%);">+                       config->ramdisk_node = find_image(config->ramdisk);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (!config->kernel_node ||</span><br><span style="color: hsl(120, 100%, 40%);">+                                (config->fdt && !config->fdt_node)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   printf("Missing image, discarding config %s.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                            config->name);</span><br><span style="color: hsl(120, 100%, 40%);">+                     list_remove(&config->list_node);</span><br><span style="color: hsl(120, 100%, 40%);">+                       continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (config->fdt_node) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (config->fdt_node->compression != CompressionNone) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         printf("FDT compression not yet supported, "</span><br><span style="color: hsl(120, 100%, 40%);">+                                       "skipping config %s.\n", config->name);</span><br><span style="color: hsl(120, 100%, 40%);">+                           list_remove(&config->list_node);</span><br><span style="color: hsl(120, 100%, 40%);">+                               continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   void *fdt_blob = config->fdt_node->data;</span><br><span style="color: hsl(120, 100%, 40%);">+                        FdtHeader *fdt_header = (FdtHeader *)fdt_blob;</span><br><span style="color: hsl(120, 100%, 40%);">+                        uint32_t fdt_offset =</span><br><span style="color: hsl(120, 100%, 40%);">+                         betohl(fdt_header->structure_offset);</span><br><span style="color: hsl(120, 100%, 40%);">+                      config->compat_pos = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+                   config->compat_rank = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (!fdt_find_compat(fdt_blob, fdt_offset,</span><br><span style="color: hsl(120, 100%, 40%);">+                                        &config->compat)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                for (i = 0; i < num_fit_kernel_compat; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                      int pos = fit_check_compat(</span><br><span style="color: hsl(120, 100%, 40%);">+                                                   &config->compat,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                       fit_kernel_compat[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+                                        if (pos >= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                            config->compat_pos = pos;</span><br><span style="color: hsl(120, 100%, 40%);">+                                          config->compat_rank = i;</span><br><span style="color: hsl(120, 100%, 40%);">+                                           break;</span><br><span style="color: hsl(120, 100%, 40%);">+                                        }</span><br><span style="color: hsl(120, 100%, 40%);">+                             }</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           printf("Config %s", config->name);</span><br><span style="color: hsl(120, 100%, 40%);">+               if (default_config_name &&</span><br><span style="color: hsl(120, 100%, 40%);">+                            !strcmp(config->name, default_config_name)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      printf(" (default)");</span><br><span style="color: hsl(120, 100%, 40%);">+                       default_config = config;</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+             printf(", kernel %s", config->kernel);</span><br><span style="color: hsl(120, 100%, 40%);">+           if (config->fdt)</span><br><span style="color: hsl(120, 100%, 40%);">+                   printf(", fdt %s", config->fdt);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (config->ramdisk)</span><br><span style="color: hsl(120, 100%, 40%);">+                       printf(", ramdisk %s", config->ramdisk);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (config->compat.name) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 printf(", compat");</span><br><span style="color: hsl(120, 100%, 40%);">+                 int bytes = config->compat.size;</span><br><span style="color: hsl(120, 100%, 40%);">+                   const char *compat_str = config->compat.data;</span><br><span style="color: hsl(120, 100%, 40%);">+                      for (int pos = 0; bytes && compat_str[0]; pos++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                            printf(" %s", compat_str);</span><br><span style="color: hsl(120, 100%, 40%);">+                          if (pos == config->compat_pos)</span><br><span style="color: hsl(120, 100%, 40%);">+                                     printf(" (match)");</span><br><span style="color: hsl(120, 100%, 40%);">+                         int len = strlen(compat_str) + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                             compat_str += len;</span><br><span style="color: hsl(120, 100%, 40%);">+                            bytes -= len;</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (config->compat_rank >= 0 && (!compat_config ||</span><br><span style="color: hsl(120, 100%, 40%);">+                          config->compat_rank < compat_config->compat_rank))</span><br><span style="color: hsl(120, 100%, 40%);">+                               compat_config = config;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+             printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   FitConfigNode *to_boot = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+        if (compat_config) {</span><br><span style="color: hsl(120, 100%, 40%);">+          to_boot = compat_config;</span><br><span style="color: hsl(120, 100%, 40%);">+              printf("Choosing best match %s for compat %s.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  to_boot->name, fit_kernel_compat[to_boot->compat_rank]);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (default_config) {</span><br><span style="color: hsl(120, 100%, 40%);">+          to_boot = default_config;</span><br><span style="color: hsl(120, 100%, 40%);">+             printf("No match, choosing default %s.\n", to_boot->name);</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              printf("No compatible or default configs. Giving up.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           // We're leaking memory here, but at this point we're beyond</span><br><span style="color: hsl(120, 100%, 40%);">+          // saving anyway.</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (to_boot->fdt_node) {</span><br><span style="color: hsl(120, 100%, 40%);">+           *dt = fdt_unflatten(to_boot->fdt_node->data);</span><br><span style="color: hsl(120, 100%, 40%);">+           if (!*dt) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   printf("Failed to unflatten the kernel's fdt.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                      return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+          }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           /* Update only if non-NULL cmd line */</span><br><span style="color: hsl(120, 100%, 40%);">+                if (cmd_line)</span><br><span style="color: hsl(120, 100%, 40%);">+                 update_chosen(*dt, cmd_line);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               update_memory(*dt);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         if (to_boot->ramdisk_node) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (to_boot->ramdisk_node->compression</span><br><span style="color: hsl(120, 100%, 40%);">+                                  != CompressionNone) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         printf("Ramdisk compression not supported.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+                  }</span><br><span style="color: hsl(120, 100%, 40%);">+                     fit_add_ramdisk(*dt, to_boot->ramdisk_node->data,</span><br><span style="color: hsl(120, 100%, 40%);">+                                       to_boot->ramdisk_node->size);</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return to_boot->kernel_node;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/25739">change 25739</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/25739"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Iee56db328d7eeffb0eaf829841243b0b9195c199 </div>
<div style="display:none"> Gerrit-Change-Number: 25739 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Patrick Rudolph <patrick.rudolph@9elements.com> </div>