From patchwork Sat Nov 17 09:18:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Goldschmidt X-Patchwork-Id: 999263 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="bvsFcwwJ"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 42xqLj1FFZz9s9m for ; Sat, 17 Nov 2018 20:19:57 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id D7495C2233E; Sat, 17 Nov 2018 09:18:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_BLOCKED, RCVD_IN_MSPIKE_H2, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id C4B72C22333; Sat, 17 Nov 2018 09:18:40 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id CA6C9C22333; Sat, 17 Nov 2018 09:18:37 +0000 (UTC) Received: from mail-wm1-f66.google.com (mail-wm1-f66.google.com [209.85.128.66]) by lists.denx.de (Postfix) with ESMTPS id 46774C2230C for ; Sat, 17 Nov 2018 09:18:34 +0000 (UTC) Received: by mail-wm1-f66.google.com with SMTP id r63-v6so776425wma.4 for ; Sat, 17 Nov 2018 01:18:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=erXrpQIDJPsLfEBBlx20usoYhOduK7V9YHV3TT0slpI=; b=bvsFcwwJJS3faU3866bEJ7H1xVutD5Kb4HNmiBchfa7wAjBvXg0SXhS5simfgrP3bp pVsbVw0ytqkxzJrYXFdYdKEKMSKVTXt3bdQOAGiCXNDLR3BOM7vBTv7AxJXYeVNx/Arb JZ3bnPTBbE0ZWHu2bkjz+cvdI+VdFDrngMIZL+kYzstlD1vrQJ0pHW9bGh8DOTHqXco3 o7UqN/fKbl6C6NHGF5ui01S9CjUscb+DFzk4pp/Oz0I3q1DtQoolUDfV20ssumIqsGLg Xp5JRNwm1Some/aYnfJazIvUTe9JOdztMjAh4uagUFiHltwPL4j2tPglIorX95BrcWzD ymFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=erXrpQIDJPsLfEBBlx20usoYhOduK7V9YHV3TT0slpI=; b=eu3sEpqYwaevv20ROKNcqfA2KwY5K/aGRvNKCZt6NEhjEnfax3GBUpfglI18m0uyCU ik+gGfm0c1h+7ivsfxuBMmjpfA0oxMXlXg5gIGZEu4QB0dTv50mO0fHKiINcM84T3Mvj /EieC0bd/v7Zjpr2awQszSqwb+EWAEWg+6H05jn4BF/kM8yE9GIm56Lqle9UAwlT6Jfa 6SK3QysLpwYkbhzVVuNGDYHNtAgWZW5mmDWgKBKMFVj5QVQ/pj5iW08lg1KWVat+B/Nf I00KjjOozPEyUtB6bJUertgR+gM/otgSX8cxzgm+7U0mbp5PisR2gRO7wnA5lSMkV8Vw +xBQ== X-Gm-Message-State: AA+aEWYFKsrv9jsH5ORMBa42DRD4APX9BCrKeqX5K2YxmOWm123X85O2 ifF2R4ez2ipBzDM/CwCbGjI= X-Google-Smtp-Source: AFSGD/WQstOeMWSJ1vY+3OGGKvVxMBH4CCwcUNGa7l2LPv0t4S9+v//WUxLPQ9zMLTvsbOxLJ5SonQ== X-Received: by 2002:a1c:5f8a:: with SMTP id t132mr1127658wmb.40.1542446313879; Sat, 17 Nov 2018 01:18:33 -0800 (PST) Received: from ubuntu.home ([2a02:8071:6a3:700:456c:50ae:6b7:768d]) by smtp.gmail.com with ESMTPSA id f18-v6sm30027642wre.57.2018.11.17.01.18.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 17 Nov 2018 01:18:32 -0800 (PST) From: Simon Goldschmidt To: Tom Rini , u-boot@lists.denx.de, Joe Hershberger Date: Sat, 17 Nov 2018 10:18:13 +0100 Message-Id: <20181117091818.15393-4-simon.k.r.goldschmidt@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181117091818.15393-1-simon.k.r.goldschmidt@gmail.com> References: <20181117091818.15393-1-simon.k.r.goldschmidt@gmail.com> Cc: Heinrich Schuchardt , Andrea Barisani Subject: [U-Boot] [PATCH v2 3/8] lib: lmb: extend lmb for checks at load time X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" This adds two new functions, lmb_alloc_addr and lmb_get_unreserved_size. lmb_alloc_addr behaves like lmb_alloc, but it tries to allocate a pre-specified address range. Unlike lmb_reserve, this address range must be inside one of the memory ranges that has been set up with lmb_add. lmb_get_unreserved_size returns the number of bytes that can be used up to the next reserved region or the end of valid ram. This can be 0 if the address passed is reserved. Signed-off-by: Simon Goldschmidt --- Changes in v2: - added lmb_get_unreserved_size() for tftp include/lmb.h | 3 +++ lib/lmb.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/include/lmb.h b/include/lmb.h index f04d058093..7d7e2a78dc 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -38,6 +38,9 @@ extern phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align phys_addr_t max_addr); extern phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr); +extern phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, + phys_size_t size); +extern phys_size_t lmb_get_unreserved_size(struct lmb *lmb, phys_addr_t addr); extern int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr); extern long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size); diff --git a/lib/lmb.c b/lib/lmb.c index 8dc703d996..9de1581972 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -324,6 +324,59 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phy return 0; } +/* + * Try to allocate a specific address range: must be in defined memory but not + * reserved + */ +phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, phys_size_t size) +{ + long j; + + /* Check if the requested address is in one of the memory regions */ + j = lmb_overlaps_region(&lmb->memory, base, size); + if (j >= 0) { + /* + * Check if the requested end address is in the same memory + * region we found. + */ + if (lmb_addrs_overlap(lmb->memory.region[j].base, + lmb->memory.region[j].size, base + size - + 1, 1)) { + /* ok, reserve the memory */ + if (!lmb_reserve(lmb, base, size)) + return base; + } + } + return 0; +} + +/* Return number of bytes from a given address that are free */ +phys_size_t lmb_get_unreserved_size(struct lmb *lmb, phys_addr_t addr) +{ + int i; + long j; + + /* check if the requested address is in the memory regions */ + j = lmb_overlaps_region(&lmb->memory, addr, 1); + if (j >= 0) { + for (i = 0; i < lmb->reserved.cnt; i++) { + if (addr < lmb->reserved.region[i].base) { + /* first reserved range > requested address */ + return lmb->reserved.region[i].base - addr; + } + if (lmb->reserved.region[i].base + + lmb->reserved.region[i].size > addr) { + /* requested addr is in this reserved range */ + return 0; + } + } + /* if we come here: no reserved ranges above requested addr */ + return lmb->memory.region[lmb->memory.cnt - 1].base + + lmb->memory.region[lmb->memory.cnt - 1].size - addr; + } + return 0; +} + int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr) { int i;