<p>Patrick Rudolph has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/25383">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">lib/bootmem: Extend bootmem_allocate_buffer<br><br>Extend bootmem_allocate_buffer to return either memory at bottom of<br>DRAM or at top of DRAM. Also pass the alignment as optional argument.<br><br>Protect the current executable, to prevent the loader from overwriting it.<br>Introduce new weak functions to guard other in use memory regions.<br>For example: TTB, CBFS cache, ATF region, ...<br><br>To be used by FIT image loading.<br>Tested on Cavium SoC.<br><br>Change-Id: I0c983ce43616147c519a43edee3b61d54eadbb9a<br>Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com><br>---<br>M src/cpu/x86/mirror_payload.c<br>M src/include/bootmem.h<br>M src/lib/bootmem.c<br>M src/lib/prog_loaders.c<br>M src/lib/selfboot.c<br>5 files changed, 72 insertions(+), 13 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/83/25383/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/cpu/x86/mirror_payload.c b/src/cpu/x86/mirror_payload.c</span><br><span>index 5f0493a..d921a26 100644</span><br><span>--- a/src/cpu/x86/mirror_payload.c</span><br><span>+++ b/src/cpu/x86/mirror_payload.c</span><br><span>@@ -46,7 +46,7 @@</span><br><span> </span><br><span>      printk(BIOS_DEBUG, "Payload aligned size: 0x%zx\n", size);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        buffer = bootmem_allocate_buffer(size);</span><br><span style="color: hsl(120, 100%, 40%);">+       buffer = bootmem_allocate_buffer(size, 0, 0);</span><br><span> </span><br><span>    if (buffer == NULL) {</span><br><span>                printk(BIOS_DEBUG, "No buffer for mirroring payload.\n");</span><br><span>diff --git a/src/include/bootmem.h b/src/include/bootmem.h</span><br><span>index 10c8d51..4235317 100644</span><br><span>--- a/src/include/bootmem.h</span><br><span>+++ b/src/include/bootmem.h</span><br><span>@@ -41,7 +41,16 @@</span><br><span> /* Return 1 if region targets usable RAM, 0 otherwise. */</span><br><span> int bootmem_region_targets_usable_ram(uint64_t start, uint64_t size);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void bootmem_prepare_payload(void);</span><br><span style="color: hsl(120, 100%, 40%);">+void bootmem_prepare_payload_arch(void);</span><br><span style="color: hsl(120, 100%, 40%);">+void bootmem_prepare_payload_platform(void);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Allocate a temporary buffer from the unused RAM areas. */</span><br><span style="color: hsl(0, 100%, 40%);">-void *bootmem_allocate_buffer(size_t size);</span><br><span style="color: hsl(120, 100%, 40%);">+void *bootmem_allocate_buffer(const size_t size, const size_t align,</span><br><span style="color: hsl(120, 100%, 40%);">+                         const size_t prefer_low_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Helper to mark region as in use */</span><br><span style="color: hsl(120, 100%, 40%);">+#define BOOTMEM_RESERVED(x) bootmem_add_range((uintptr_t)_##x, _##x##_size, \</span><br><span style="color: hsl(120, 100%, 40%);">+                                        LB_MEM_RESERVED);</span><br><span> </span><br><span> #endif /* BOOTMEM_H */</span><br><span>diff --git a/src/lib/bootmem.c b/src/lib/bootmem.c</span><br><span>index ea02a16..6f4bb04 100644</span><br><span>--- a/src/lib/bootmem.c</span><br><span>+++ b/src/lib/bootmem.c</span><br><span>@@ -20,6 +20,7 @@</span><br><span> #include <cbmem.h></span><br><span> #include <device/resource.h></span><br><span> #include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <symbols.h></span><br><span> </span><br><span> static struct memranges bootmem;</span><br><span> </span><br><span>@@ -126,7 +127,44 @@</span><br><span>     return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void *bootmem_allocate_buffer(size_t size)</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Overwrite on arch level to guard against overwriting in use memory regions.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Possible regions: TTB</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void __attribute__((weak)) bootmem_prepare_payload_arch(void)</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%);">+ * Overwrite on platform level to guard against overwriting in use memory</span><br><span style="color: hsl(120, 100%, 40%);">+ * regions.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Possible regions: TIMESTAMPS</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void __attribute__((weak)) bootmem_prepare_payload_platform(void)</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%);">+void bootmem_prepare_payload(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Mark current program as reserved. */</span><br><span style="color: hsl(120, 100%, 40%);">+       BOOTMEM_RESERVED(program)</span><br><span style="color: hsl(120, 100%, 40%);">+     BOOTMEM_RESERVED(stack)</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%);">+ * Allocate a slice of memory for payload related operations.</span><br><span style="color: hsl(120, 100%, 40%);">+ * The returned buffer doesn't overlap with anything in use and targets</span><br><span style="color: hsl(120, 100%, 40%);">+ * usable DRAM.</span><br><span style="color: hsl(120, 100%, 40%);">+ * @size: Size of buffer to allocate in bytes.</span><br><span style="color: hsl(120, 100%, 40%);">+ * @align: Alignment of buffer in bytes. Set to 0 if not used.</span><br><span style="color: hsl(120, 100%, 40%);">+ * @prefer_low_addr: Set to 1 to get a buffer from start of DRAM.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns a buffer with given alignment in 32bit address space.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns NULL on error.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void *bootmem_allocate_buffer(const size_t size, const size_t align,</span><br><span style="color: hsl(120, 100%, 40%);">+                           const size_t prefer_low_addr)</span><br><span> {</span><br><span>     const struct range_entry *r;</span><br><span>         const struct range_entry *region;</span><br><span>@@ -136,10 +174,10 @@</span><br><span>    resource_t end;</span><br><span> </span><br><span>  /* 4KiB alignment. */</span><br><span style="color: hsl(0, 100%, 40%);">-   size = ALIGN(size, 4096);</span><br><span style="color: hsl(120, 100%, 40%);">+     const size_t real_size = ALIGN(size, MAX(4096, align));</span><br><span>      region = NULL;</span><br><span>       memranges_each_entry(r, &bootmem) {</span><br><span style="color: hsl(0, 100%, 40%);">-         if (range_entry_size(r) < size)</span><br><span style="color: hsl(120, 100%, 40%);">+            if (range_entry_size(r) < real_size)</span><br><span>                      continue;</span><br><span> </span><br><span>                if (range_entry_tag(r) != LB_MEM_RAM)</span><br><span>@@ -152,24 +190,32 @@</span><br><span>                if (end > max_addr)</span><br><span>                       end = max_addr;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-             if ((end - range_entry_base(r)) < size)</span><br><span style="color: hsl(120, 100%, 40%);">+            if ((end - range_entry_base(r)) < real_size)</span><br><span>                      continue;</span><br><span> </span><br><span>                region = r;</span><br><span style="color: hsl(120, 100%, 40%);">+           if (prefer_low_addr)</span><br><span style="color: hsl(120, 100%, 40%);">+                  break;</span><br><span>       }</span><br><span> </span><br><span>        if (region == NULL)</span><br><span>          return NULL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        /* region now points to the highest usable region for the given size. */</span><br><span style="color: hsl(120, 100%, 40%);">+      /*</span><br><span style="color: hsl(120, 100%, 40%);">+     * region now points to either the lowest or to the highest usable</span><br><span style="color: hsl(120, 100%, 40%);">+     * region for the given size.</span><br><span style="color: hsl(120, 100%, 40%);">+  */</span><br><span>  begin = range_entry_base(region);</span><br><span>    end = range_entry_end(region);</span><br><span style="color: hsl(0, 100%, 40%);">-  if (end > max_addr)</span><br><span style="color: hsl(0, 100%, 40%);">-          end = max_addr;</span><br><span style="color: hsl(0, 100%, 40%);">- begin = end - size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!prefer_low_addr) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (end > max_addr)</span><br><span style="color: hsl(120, 100%, 40%);">+                        end = max_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+               begin = end - real_size;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span> </span><br><span>        /* Mark buffer as unusuable for future buffer use. */</span><br><span style="color: hsl(0, 100%, 40%);">-   bootmem_add_range(begin, size, LB_MEM_UNUSABLE);</span><br><span style="color: hsl(120, 100%, 40%);">+      bootmem_add_range(begin, real_size, LB_MEM_UNUSABLE);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       return (void *)(uintptr_t)begin;</span><br><span style="color: hsl(120, 100%, 40%);">+      return (void *)((uintptr_t)ALIGN_UP(begin, align));</span><br><span> }</span><br><span>diff --git a/src/lib/prog_loaders.c b/src/lib/prog_loaders.c</span><br><span>index 128869b..0aa415a 100644</span><br><span>--- a/src/lib/prog_loaders.c</span><br><span>+++ b/src/lib/prog_loaders.c</span><br><span>@@ -29,6 +29,7 @@</span><br><span> #include <stage_cache.h></span><br><span> #include <symbols.h></span><br><span> #include <timestamp.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <bootmem.h></span><br><span> </span><br><span> /* Only can represent up to 1 byte less than size_t. */</span><br><span> const struct mem_region_device addrspace_32bit =</span><br><span>@@ -178,6 +179,9 @@</span><br><span>               goto out;</span><br><span> </span><br><span>        mirror_payload(payload);</span><br><span style="color: hsl(120, 100%, 40%);">+      bootmem_prepare_payload();</span><br><span style="color: hsl(120, 100%, 40%);">+    bootmem_prepare_payload_arch();</span><br><span style="color: hsl(120, 100%, 40%);">+       bootmem_prepare_payload_platform();</span><br><span> </span><br><span>      /* Pass cbtables to payload if architecture desires it. */</span><br><span>   prog_set_entry(payload, selfload(payload, true),</span><br><span>diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c</span><br><span>index 160e8f5..9b97f9d 100644</span><br><span>--- a/src/lib/selfboot.c</span><br><span>+++ b/src/lib/selfboot.c</span><br><span>@@ -101,7 +101,7 @@</span><br><span>   */</span><br><span>  lb_size = req_size + lb_size;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       buffer = bootmem_allocate_buffer(lb_size);</span><br><span style="color: hsl(120, 100%, 40%);">+    buffer = bootmem_allocate_buffer(lb_size, 0, 0);</span><br><span> </span><br><span>         printk(BIOS_SPEW, "Bounce Buffer at %p, %lu bytes\n", buffer, lb_size);</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/25383">change 25383</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/25383"/><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: I0c983ce43616147c519a43edee3b61d54eadbb9a </div>
<div style="display:none"> Gerrit-Change-Number: 25383 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Patrick Rudolph <patrick.rudolph@9elements.com> </div>