From patchwork Wed Mar 30 14:38:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 603385 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 3qZqyS13LDz9snm for ; Thu, 31 Mar 2016 01:38:40 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id E0A0EA76CC; Wed, 30 Mar 2016 16:38:37 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id aoTvgdj6nfc5; Wed, 30 Mar 2016 16:38:37 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 533ECA7646; Wed, 30 Mar 2016 16:38:37 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 5FF82A7646 for ; Wed, 30 Mar 2016 16:38:34 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8Rm7wforhKvP for ; Wed, 30 Mar 2016 16:38:34 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by theia.denx.de (Postfix) with ESMTPS id 28821A749F for ; Wed, 30 Mar 2016 16:38:30 +0200 (CEST) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id D8823AB22; Wed, 30 Mar 2016 14:38:28 +0000 (UTC) From: Alexander Graf To: u-boot@lists.denx.de Date: Wed, 30 Mar 2016 16:38:29 +0200 Message-Id: <1459348709-139552-1-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.8.5.6 Cc: leif.lindholm@linaro.org Subject: [U-Boot] [PATCH] efi_loader: Always allocate the highest available address X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Some EFI applications (grub2) expect that an allocation always returns the highest available memory address for the given size. Without this, we may run into situations where the initrd gets allocated at a lower address than the kernel. This patch fixes booting in such situations for me. Signed-off-by: Alexander Graf --- lib/efi_loader/efi_memory.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index c82b53f..8a1e249 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -27,6 +28,31 @@ struct efi_mem_list { LIST_HEAD(efi_mem); /* + * Sorts the memory list from highest address to lowest address + * + * When allocating memory we should always start from the highest + * address chunk, so sort the memory list such that the first list + * iterator gets the highest address and goes lower from there. + */ +static int efi_mem_cmp(void *priv, struct list_head *a, struct list_head *b) +{ + struct efi_mem_list *mema = list_entry(a, struct efi_mem_list, link); + struct efi_mem_list *memb = list_entry(b, struct efi_mem_list, link); + + if (mema->desc.physical_start == memb->desc.physical_start) + return 0; + else if (mema->desc.physical_start < memb->desc.physical_start) + return 1; + else + return -1; +} + +static void efi_mem_sort(void) +{ + list_sort(NULL, &efi_mem, efi_mem_cmp); +} + +/* * Unmaps all memory occupied by the carve_desc region from the * list entry pointed to by map. * @@ -142,6 +168,9 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type, /* Add our new map */ list_add_tail(&newlist->link, &efi_mem); + /* And make sure memory is listed in descending order */ + efi_mem_sort(); + return start; }