<p>Jonathan Neuschäfer has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/c/coreboot/+/30292">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">[WIP] Enable FIT support on RISC-V<br><br>WORK IN PROGRESS: This patch has to be cleaned up in a few ways, and it<br>doesn't make linux boot all the way.<br><br>Change-Id: I5ebc6cc2cc9e328f36d70fba13555386bb8c29d6<br>Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net><br>---<br>M Documentation/lib/payloads/fit.md<br>M payloads/Kconfig<br>A riscv.its<br>A spike.dts<br>M src/arch/riscv/Makefile.inc<br>M src/arch/riscv/boot.c<br>A src/arch/riscv/fit_payload.c<br>M src/arch/riscv/virtual_memory.c<br>8 files changed, 324 insertions(+), 7 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/92/30292/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/Documentation/lib/payloads/fit.md b/Documentation/lib/payloads/fit.md</span><br><span>index 53be92e..a7e6890 100644</span><br><span>--- a/Documentation/lib/payloads/fit.md</span><br><span>+++ b/Documentation/lib/payloads/fit.md</span><br><span>@@ -6,6 +6,7 @@</span><br><span> ## Supported architectures</span><br><span> </span><br><span> * aarch64</span><br><span style="color: hsl(120, 100%, 40%);">+* riscv</span><br><span> </span><br><span> ## Supported FIT sections</span><br><span> </span><br><span>@@ -24,6 +25,7 @@</span><br><span> ## Architecture specifics</span><br><span> </span><br><span> The FIT parser needs architecure support.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> ### aarch64</span><br><span> The source code can be found in `src/arch/arm64/fit.c`.</span><br><span> </span><br><span>@@ -31,6 +33,10 @@</span><br><span> format and it needs a devicetree (a section named 'fdt') to boot.</span><br><span> The kernel will be placed close to "*DRAMSTART*".</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+### RISC-V</span><br><span style="color: hsl(120, 100%, 40%);">+ASDFASDF</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> ### Other</span><br><span> Other architectures aren't supported.</span><br><span> </span><br><span>diff --git a/payloads/Kconfig b/payloads/Kconfig</span><br><span>index c7a7ba6..0c5ce8f 100644</span><br><span>--- a/payloads/Kconfig</span><br><span>+++ b/payloads/Kconfig</span><br><span>@@ -30,7 +30,7 @@</span><br><span> </span><br><span> config PAYLOAD_FIT</span><br><span>        bool "A FIT payload"</span><br><span style="color: hsl(0, 100%, 40%);">-  depends on ARCH_ARM64</span><br><span style="color: hsl(120, 100%, 40%);">+ depends on ARCH_ARM64 || ARCH_RISCV</span><br><span>  select PAYLOAD_FIT_SUPPORT</span><br><span>   help</span><br><span>           Select this option if you have a payload image (a FIT file) which</span><br><span>diff --git a/riscv.its b/riscv.its</span><br><span>new file mode 100644</span><br><span>index 0000000..453de1a</span><br><span>--- /dev/null</span><br><span>+++ b/riscv.its</span><br><span>@@ -0,0 +1,59 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* TODO: move to a better place! */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/dts-v1/;</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%);">+        description = "Simple image with single Linux kernel and FDT blob";</span><br><span style="color: hsl(120, 100%, 40%);">+ #address-cells = <1>;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ images {</span><br><span style="color: hsl(120, 100%, 40%);">+              kernel {</span><br><span style="color: hsl(120, 100%, 40%);">+                      description = "Vanilla Linux kernel";</span><br><span style="color: hsl(120, 100%, 40%);">+                       data = /incbin/("Image.riscv.lzma");</span><br><span style="color: hsl(120, 100%, 40%);">+                        type = "kernel";</span><br><span style="color: hsl(120, 100%, 40%);">+                    arch = "riscv";</span><br><span style="color: hsl(120, 100%, 40%);">+                     os = "linux";</span><br><span style="color: hsl(120, 100%, 40%);">+                       compression = "lzma";</span><br><span style="color: hsl(120, 100%, 40%);">+                       load = <0x80000000>;</span><br><span style="color: hsl(120, 100%, 40%);">+                    entry = <0x80000000>;</span><br><span style="color: hsl(120, 100%, 40%);">+                   hash-1 {</span><br><span style="color: hsl(120, 100%, 40%);">+                              algo = "crc32";</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%);">+            fdt-1 {</span><br><span style="color: hsl(120, 100%, 40%);">+                       description = "Flattened Device Tree blob";</span><br><span style="color: hsl(120, 100%, 40%);">+                 data = /incbin/("spike.dtb");</span><br><span style="color: hsl(120, 100%, 40%);">+                       type = "flat_dt";</span><br><span style="color: hsl(120, 100%, 40%);">+                   arch = "arm64";</span><br><span style="color: hsl(120, 100%, 40%);">+                     compression = "none";</span><br><span style="color: hsl(120, 100%, 40%);">+                       hash-1 {</span><br><span style="color: hsl(120, 100%, 40%);">+                              algo = "crc32";</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%);">+            ramdisk-1 {</span><br><span style="color: hsl(120, 100%, 40%);">+                   description = "Compressed Initramfs";</span><br><span style="color: hsl(120, 100%, 40%);">+                       data = /incbin/("initramfs.cpio.xz");</span><br><span style="color: hsl(120, 100%, 40%);">+                       type = "ramdisk";</span><br><span style="color: hsl(120, 100%, 40%);">+                   arch = "arm64";</span><br><span style="color: hsl(120, 100%, 40%);">+                     os = "linux";</span><br><span style="color: hsl(120, 100%, 40%);">+                       compression = "none";</span><br><span style="color: hsl(120, 100%, 40%);">+                       load = <00000000>;</span><br><span style="color: hsl(120, 100%, 40%);">+                      entry = <00000000>;</span><br><span style="color: hsl(120, 100%, 40%);">+                     hash-1 {</span><br><span style="color: hsl(120, 100%, 40%);">+                              algo = "sha1";</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%);">+  configurations {</span><br><span style="color: hsl(120, 100%, 40%);">+              default = "conf-1";</span><br><span style="color: hsl(120, 100%, 40%);">+         conf-1 {</span><br><span style="color: hsl(120, 100%, 40%);">+                      description = "Boot Linux kernel with FDT blob";</span><br><span style="color: hsl(120, 100%, 40%);">+                    kernel = "kernel";</span><br><span style="color: hsl(120, 100%, 40%);">+                  fdt = "fdt-1";</span><br><span style="color: hsl(120, 100%, 40%);">+                      //ramdisk = "ramdisk-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%);">+};</span><br><span>diff --git a/spike.dts b/spike.dts</span><br><span>new file mode 100644</span><br><span>index 0000000..f1827d3</span><br><span>--- /dev/null</span><br><span>+++ b/spike.dts</span><br><span>@@ -0,0 +1,59 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/dts-v1/;</span><br><span style="color: hsl(120, 100%, 40%);">+// magic:          0xd00dfeed</span><br><span style="color: hsl(120, 100%, 40%);">+// totalsize:               0x442 (1090)</span><br><span style="color: hsl(120, 100%, 40%);">+// off_dt_struct: 0x38</span><br><span style="color: hsl(120, 100%, 40%);">+// off_dt_strings:        0x370</span><br><span style="color: hsl(120, 100%, 40%);">+// off_mem_rsvmap:       0x28</span><br><span style="color: hsl(120, 100%, 40%);">+// version:               17</span><br><span style="color: hsl(120, 100%, 40%);">+// last_comp_version:       16</span><br><span style="color: hsl(120, 100%, 40%);">+// boot_cpuid_phys: 0x0</span><br><span style="color: hsl(120, 100%, 40%);">+// size_dt_strings:        0xd2</span><br><span style="color: hsl(120, 100%, 40%);">+// size_dt_struct:        0x338</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%);">+    #address-cells = <0x00000002>;</span><br><span style="color: hsl(120, 100%, 40%);">+    #size-cells = <0x00000002>;</span><br><span style="color: hsl(120, 100%, 40%);">+    compatible = "ucbbar,spike-bare-dev";</span><br><span style="color: hsl(120, 100%, 40%);">+    model = "ucbbar,spike-bare";</span><br><span style="color: hsl(120, 100%, 40%);">+    cpus {</span><br><span style="color: hsl(120, 100%, 40%);">+        #address-cells = <0x00000001>;</span><br><span style="color: hsl(120, 100%, 40%);">+        #size-cells = <0x00000000>;</span><br><span style="color: hsl(120, 100%, 40%);">+        timebase-frequency = <10000000>;</span><br><span style="color: hsl(120, 100%, 40%);">+        cpu@0 {</span><br><span style="color: hsl(120, 100%, 40%);">+            device_type = "cpu";</span><br><span style="color: hsl(120, 100%, 40%);">+            reg = <0x00000000>;</span><br><span style="color: hsl(120, 100%, 40%);">+            status = "okay";</span><br><span style="color: hsl(120, 100%, 40%);">+            compatible = "riscv";</span><br><span style="color: hsl(120, 100%, 40%);">+            riscv,isa = "rv64imafdc";</span><br><span style="color: hsl(120, 100%, 40%);">+            mmu-type = "riscv,sv48";</span><br><span style="color: hsl(120, 100%, 40%);">+            clock-frequency = <1000000000>;</span><br><span style="color: hsl(120, 100%, 40%);">+            interrupt-controller {</span><br><span style="color: hsl(120, 100%, 40%);">+                #interrupt-cells = <0x00000001>;</span><br><span style="color: hsl(120, 100%, 40%);">+                interrupt-controller;</span><br><span style="color: hsl(120, 100%, 40%);">+                compatible = "riscv,cpu-intc";</span><br><span style="color: hsl(120, 100%, 40%);">+                linux,phandle = <0x00000001>;</span><br><span style="color: hsl(120, 100%, 40%);">+                phandle = <0x00000001>;</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%);">+    memory@80000000 {</span><br><span style="color: hsl(120, 100%, 40%);">+        device_type = "memory";</span><br><span style="color: hsl(120, 100%, 40%);">+        reg = <0x00000000 0x80000000 0x00000000 0x40000000>;</span><br><span style="color: hsl(120, 100%, 40%);">+    };</span><br><span style="color: hsl(120, 100%, 40%);">+    soc {</span><br><span style="color: hsl(120, 100%, 40%);">+        #address-cells = <0x00000002>;</span><br><span style="color: hsl(120, 100%, 40%);">+        #size-cells = <0x00000002>;</span><br><span style="color: hsl(120, 100%, 40%);">+        compatible = "ucbbar,spike-bare-soc", "simple-bus";</span><br><span style="color: hsl(120, 100%, 40%);">+        ranges;</span><br><span style="color: hsl(120, 100%, 40%);">+        clint@2000000 {</span><br><span style="color: hsl(120, 100%, 40%);">+            compatible = "riscv,clint0";</span><br><span style="color: hsl(120, 100%, 40%);">+            interrupts-extended = <0x00000001 0x00000003 0x00000001 0x00000007>;</span><br><span style="color: hsl(120, 100%, 40%);">+            reg = <0x00000000 0x02000000 0x00000000 0x000c0000>;</span><br><span style="color: hsl(120, 100%, 40%);">+        };</span><br><span style="color: hsl(120, 100%, 40%);">+        uart@2100000 {</span><br><span style="color: hsl(120, 100%, 40%);">+            compatible = "serial";</span><br><span style="color: hsl(120, 100%, 40%);">+            reg = <0x00000000 0x02100000 0x00000000 0x00000008>;</span><br><span style="color: hsl(120, 100%, 40%);">+            reg-shift = <0x00000000>;</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>diff --git a/src/arch/riscv/Makefile.inc b/src/arch/riscv/Makefile.inc</span><br><span>index aee4b3b..36ea047 100644</span><br><span>--- a/src/arch/riscv/Makefile.inc</span><br><span>+++ b/src/arch/riscv/Makefile.inc</span><br><span>@@ -128,6 +128,7 @@</span><br><span> ramstage-y += tables.c</span><br><span> ramstage-y += payload.S</span><br><span> ramstage-y += pmp.c</span><br><span style="color: hsl(120, 100%, 40%);">+ramstage-y += fit_payload.c</span><br><span> ramstage-y += \</span><br><span>     $(top)/src/lib/memchr.c \</span><br><span>    $(top)/src/lib/memcmp.c \</span><br><span>diff --git a/src/arch/riscv/boot.c b/src/arch/riscv/boot.c</span><br><span>index 04fba07..69fb713 100644</span><br><span>--- a/src/arch/riscv/boot.c</span><br><span>+++ b/src/arch/riscv/boot.c</span><br><span>@@ -35,12 +35,18 @@</span><br><span>     void riscvpayload(const void *fdt, void *payload);</span><br><span> </span><br><span>       if (ENV_RAMSTAGE && prog_type(prog) == PROG_PAYLOAD) {</span><br><span style="color: hsl(0, 100%, 40%);">-          /*</span><br><span style="color: hsl(0, 100%, 40%);">-               * FIXME: This is wrong and will crash. Linux can't (in early</span><br><span style="color: hsl(0, 100%, 40%);">-                * boot) access memory that's before its own loading address.</span><br><span style="color: hsl(0, 100%, 40%);">-                * We need to copy the FDT to a place where Linux can access it.</span><br><span style="color: hsl(0, 100%, 40%);">-                 */</span><br><span style="color: hsl(0, 100%, 40%);">-             const void *fdt = rom_fdt;</span><br><span style="color: hsl(120, 100%, 40%);">+            const void *arg = prog_entry_arg(prog);</span><br><span style="color: hsl(120, 100%, 40%);">+               const void *fdt;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            if (arg)</span><br><span style="color: hsl(120, 100%, 40%);">+                      fdt = arg;</span><br><span style="color: hsl(120, 100%, 40%);">+            else</span><br><span style="color: hsl(120, 100%, 40%);">+                  /*</span><br><span style="color: hsl(120, 100%, 40%);">+                     * FIXME: This is wrong and will crash. Linux can't (in early</span><br><span style="color: hsl(120, 100%, 40%);">+                      * boot) access memory that's before its own loading address.</span><br><span style="color: hsl(120, 100%, 40%);">+                      * We need to copy the FDT to a place where Linux can access it.</span><br><span style="color: hsl(120, 100%, 40%);">+                       */</span><br><span style="color: hsl(120, 100%, 40%);">+                   fdt = rom_fdt;</span><br><span> </span><br><span>           printk(BIOS_SPEW, "FDT is at %p\n", fdt);</span><br><span>          printk(BIOS_SPEW, "OK, let's go\n");</span><br><span>diff --git a/src/arch/riscv/fit_payload.c b/src/arch/riscv/fit_payload.c</span><br><span>new file mode 100644</span><br><span>index 0000000..920c922</span><br><span>--- /dev/null</span><br><span>+++ b/src/arch/riscv/fit_payload.c</span><br><span>@@ -0,0 +1,185 @@</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%);">+ * Copyright 2018 Facebook, Inc.</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 <console/console.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <bootmem.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <program_loading.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <commonlib/compression.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <commonlib/cbfs_serialized.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <lib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <fit.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <endian.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define MAX_KERNEL_SIZE (64*MiB)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static size_t get_kernel_size(const struct fit_image_node *node)</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%);">+     * Since we don't have a way to determine the uncompressed size of the</span><br><span style="color: hsl(120, 100%, 40%);">+     * kernel, we have to keep as much memory as possible free for use by</span><br><span style="color: hsl(120, 100%, 40%);">+  * the kernel immediately after the end of the kernel image. The amount</span><br><span style="color: hsl(120, 100%, 40%);">+        * of space required will vary depending on selected features, and is</span><br><span style="color: hsl(120, 100%, 40%);">+  * effectively unbound.</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%);">+ printk(BIOS_INFO,</span><br><span style="color: hsl(120, 100%, 40%);">+            "FIT: Leaving additional %u MiB of free space after kernel.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+             MAX_KERNEL_SIZE >> 20);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return node->size + MAX_KERNEL_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 bool fit_place_kernel(const struct range_entry *r, void *arg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct region *region = arg;</span><br><span style="color: hsl(120, 100%, 40%);">+  resource_t start;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (range_entry_tag(r) != BM_MEM_RAM)</span><br><span style="color: hsl(120, 100%, 40%);">+         return true;</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%);">+     * The Image must be placed text_offset bytes from a 2MB aligned base</span><br><span style="color: hsl(120, 100%, 40%);">+  * address anywhere in usable system RAM and called there. The region</span><br><span style="color: hsl(120, 100%, 40%);">+  * between the 2 MB aligned base address and the start of the image has</span><br><span style="color: hsl(120, 100%, 40%);">+        * no special significance to the kernel, and may be used for other</span><br><span style="color: hsl(120, 100%, 40%);">+    * purposes.</span><br><span style="color: hsl(120, 100%, 40%);">+   *</span><br><span style="color: hsl(120, 100%, 40%);">+     * If the reserved memory (BL31 for example) is smaller than text_offset</span><br><span style="color: hsl(120, 100%, 40%);">+       * we can use the 2 MiB base address, otherwise use the next 2 MiB page.</span><br><span style="color: hsl(120, 100%, 40%);">+       * It's not mandatory, but wastes less memory below the kernel.</span><br><span style="color: hsl(120, 100%, 40%);">+    */</span><br><span style="color: hsl(120, 100%, 40%);">+   start = ALIGN_DOWN(range_entry_base(r), 2 * MiB);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (start < range_entry_base(r))</span><br><span style="color: hsl(120, 100%, 40%);">+           start += 2 * MiB;</span><br><span style="color: hsl(120, 100%, 40%);">+     /*</span><br><span style="color: hsl(120, 100%, 40%);">+     * At least image_size bytes from the start of the image must be free</span><br><span style="color: hsl(120, 100%, 40%);">+  * for use by the kernel.</span><br><span style="color: hsl(120, 100%, 40%);">+      */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (start + region->size < range_entry_end(r)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                region->offset = (size_t)start;</span><br><span style="color: hsl(120, 100%, 40%);">+            return false;</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 true;</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%);">+ * Place the region in free memory range.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * The caller has to set region->offset to the minimum allowed address.</span><br><span style="color: hsl(120, 100%, 40%);">+ * The region->offset is usually 0 on kernel >v4.6 and kernel_base + kernel_size</span><br><span style="color: hsl(120, 100%, 40%);">+ * on kernel <v4.6.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static bool fit_place_mem(const struct range_entry *r, void *arg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct region *region = arg;</span><br><span style="color: hsl(120, 100%, 40%);">+  resource_t start;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (range_entry_tag(r) != BM_MEM_RAM)</span><br><span style="color: hsl(120, 100%, 40%);">+         return true;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Linux 4.15 doesn't like 4KiB alignment. Align to 1 MiB for now. */</span><br><span style="color: hsl(120, 100%, 40%);">+     start = ALIGN_UP(MAX(region->offset, range_entry_base(r)), 1 * MiB);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (start + region->size < range_entry_end(r)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                region->offset = (size_t)start;</span><br><span style="color: hsl(120, 100%, 40%);">+            return false;</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 true;</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%);">+bool fit_payload_arch(struct prog *payload, struct fit_config_node *config,</span><br><span style="color: hsl(120, 100%, 40%);">+                      struct region *kernel,</span><br><span style="color: hsl(120, 100%, 40%);">+                struct region *fdt,</span><br><span style="color: hsl(120, 100%, 40%);">+                   struct region *initrd)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       bool place_anywhere;</span><br><span style="color: hsl(120, 100%, 40%);">+  void *arg = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!config->fdt || !fdt) {</span><br><span style="color: hsl(120, 100%, 40%);">+                printk(BIOS_CRIT, "CRIT: Providing a valid FDT is mandatory to "</span><br><span style="color: hsl(120, 100%, 40%);">+                   "boot a RISC-V kernel!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return false;</span><br><span style="color: hsl(120, 100%, 40%);">+         /* TODO: Fall back to the ROM FDT? */</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 kernel size from image header, if possible */</span><br><span style="color: hsl(120, 100%, 40%);">+       kernel->size = get_kernel_size(config->kernel_node);</span><br><span style="color: hsl(120, 100%, 40%);">+    printk(BIOS_DEBUG, "FIT: Using kernel size of 0x%zx bytes\n",</span><br><span style="color: hsl(120, 100%, 40%);">+              kernel->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%);">+     * The code assumes that bootmem_walk provides a sorted list of memory</span><br><span style="color: hsl(120, 100%, 40%);">+         * regions, starting from the lowest address.</span><br><span style="color: hsl(120, 100%, 40%);">+  * The order of the calls here doesn't matter, as the placement is</span><br><span style="color: hsl(120, 100%, 40%);">+         * enforced in the called functions.</span><br><span style="color: hsl(120, 100%, 40%);">+   * For details check code on top.</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 (!bootmem_walk(fit_place_kernel, kernel))</span><br><span style="color: hsl(120, 100%, 40%);">+          return false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Mark as reserved for future allocations. */</span><br><span style="color: hsl(120, 100%, 40%);">+        bootmem_add_range(kernel->offset, kernel->size, BM_MEM_PAYLOAD);</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%);">+     * NOTE: versions prior to v4.6 cannot make use of memory below the</span><br><span style="color: hsl(120, 100%, 40%);">+    * physical offset of the Image so it is recommended that the Image be</span><br><span style="color: hsl(120, 100%, 40%);">+         * placed as close as possible to the start of system RAM.</span><br><span style="color: hsl(120, 100%, 40%);">+     *</span><br><span style="color: hsl(120, 100%, 40%);">+     * For kernel <v4.6 the INITRD and FDT can't be placed below the kernel.</span><br><span style="color: hsl(120, 100%, 40%);">+        * In that case set region offset to an address on top of kernel.</span><br><span style="color: hsl(120, 100%, 40%);">+      */</span><br><span style="color: hsl(120, 100%, 40%);">+   place_anywhere = false;</span><br><span style="color: hsl(120, 100%, 40%);">+       printk(BIOS_DEBUG, "FIT: Placing FDT and INITRD %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+             place_anywhere ? "anywhere" : "on top of kernel");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Place INITRD */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (config->ramdisk) {</span><br><span style="color: hsl(120, 100%, 40%);">+             if (place_anywhere)</span><br><span style="color: hsl(120, 100%, 40%);">+                   initrd->offset = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                else</span><br><span style="color: hsl(120, 100%, 40%);">+                  initrd->offset = kernel->offset + kernel->size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            if (!bootmem_walk(fit_place_mem, initrd))</span><br><span style="color: hsl(120, 100%, 40%);">+                     return false;</span><br><span style="color: hsl(120, 100%, 40%);">+         /* Mark as reserved for future allocations. */</span><br><span style="color: hsl(120, 100%, 40%);">+                bootmem_add_range(initrd->offset, initrd->size, BM_MEM_PAYLOAD);</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%);">+   /* Place FDT */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (place_anywhere)</span><br><span style="color: hsl(120, 100%, 40%);">+           fdt->offset = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   else</span><br><span style="color: hsl(120, 100%, 40%);">+          fdt->offset = kernel->offset + kernel->size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!bootmem_walk(fit_place_mem, fdt))</span><br><span style="color: hsl(120, 100%, 40%);">+                return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Mark as reserved for future allocations. */</span><br><span style="color: hsl(120, 100%, 40%);">+        bootmem_add_range(fdt->offset, fdt->size, BM_MEM_PAYLOAD);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Kernel expects FDT as argument */</span><br><span style="color: hsl(120, 100%, 40%);">+  arg = (void *)fdt->offset;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       prog_set_entry(payload, (void *)kernel->offset, arg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    bootmem_dump_ranges();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return true;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/arch/riscv/virtual_memory.c b/src/arch/riscv/virtual_memory.c</span><br><span>index d9bae2a..ec0e89a 100644</span><br><span>--- a/src/arch/riscv/virtual_memory.c</span><br><span>+++ b/src/arch/riscv/virtual_memory.c</span><br><span>@@ -16,6 +16,7 @@</span><br><span> </span><br><span> #include <arch/cpu.h></span><br><span> #include <arch/encoding.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <console/console.h></span><br><span> #include <stdint.h></span><br><span> #include <vm.h></span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/c/coreboot/+/30292">change 30292</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/c/coreboot/+/30292"/><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-Change-Id: I5ebc6cc2cc9e328f36d70fba13555386bb8c29d6 </div>
<div style="display:none"> Gerrit-Change-Number: 30292 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Jonathan Neuschäfer <j.neuschaefer@gmx.net> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>