From patchwork Sun Sep 20 00:49:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1367765 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=eSMLaIS2; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Bv8BP3tJ6z9sSC for ; Sun, 20 Sep 2020 10:50:37 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 6FD2782543; Sun, 20 Sep 2020 02:49:54 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="eSMLaIS2"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 8641082528; Sun, 20 Sep 2020 02:49:44 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-5.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-oi1-x242.google.com (mail-oi1-x242.google.com [IPv6:2607:f8b0:4864:20::242]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 316B682527 for ; Sun, 20 Sep 2020 02:49:40 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-oi1-x242.google.com with SMTP id i17so12253190oig.10 for ; Sat, 19 Sep 2020 17:49:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wuqFhBLok1JKdeuakQ1aTdNtM6cGX4k9JvCcJU2k6c4=; b=eSMLaIS2H3L/KwixQZurMhQqWBI2Dvx5iHBS2+2bf0F5G7siGqoKZTq7u4Wp7PBhj4 G3QmQhVsExnnGZIExm1GHyD1+47/o1tf4zz9Wttk7XjS7HTE/Nvf3ESW4/JKOoenFZlQ 4iq/pV6bFXW0hbCdMfXl78NMt20wBZyhWC3wc= 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:mime-version:content-transfer-encoding; bh=wuqFhBLok1JKdeuakQ1aTdNtM6cGX4k9JvCcJU2k6c4=; b=iHSA3qVvOp7b5bueiORuesZEz1P9trL7zqsWLAhkdL6pasFaBNrGatLMQyW47ne2YX 6C2DkPj7/O4DVX/QOu9hkU79rooAYCMj4fp7/LcenL0SwBvsyQZXOCGcdYYgmaQkmv7Q ACHw4pir773yXXOCKUNSTiLWELFLwAMl2FJD4lc2CXkq4oiR2UcUcfVUXMCAv3PDnJD4 SmednyGsMb6Wj5HnQPFUkmUK227+cDYMQG2XwCVt0ev8AsXd3lED0z1HqpmdQx3BH4/L gX2KmgJ/qVAwVpXR18TM0SjxLCHOS1eG99pGMJlhKkdTAXW81azRMGWfcn1R95jVIyO2 uVuQ== X-Gm-Message-State: AOAM532gCZZNm/jgj6qRDD4dXMGiEp9lzVhvWfAdHI5Prz4QBdrv/PoF vOZTodqaVKQL+5LsUBPsxiBuAK8TMTkrID4x X-Google-Smtp-Source: ABdhPJx6kce6a70zcUaNw/Q82ex50Mt6VNv1NqwEPmQ4/R/27xU1f+C1N7VMdfdhgF9TIw6eXZKx3w== X-Received: by 2002:aca:5106:: with SMTP id f6mr13011169oib.101.1600562978771; Sat, 19 Sep 2020 17:49:38 -0700 (PDT) Received: from localhost.localdomain (c-73-14-175-90.hsd1.co.comcast.net. [73.14.175.90]) by smtp.gmail.com with ESMTPSA id w12sm6234168oow.22.2020.09.19.17.49.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 19 Sep 2020 17:49:38 -0700 (PDT) From: Simon Glass To: U-Boot Mailing List Cc: Simon Glass , Philippe Reynes Subject: [PATCH 4/5] bloblist: Allow custom alignment for blobs Date: Sat, 19 Sep 2020 18:49:29 -0600 Message-Id: <20200919184909.4.I2714a2d96b5b651fea0cb4065d0684a2600861e9@changeid> X-Mailer: git-send-email 2.28.0.681.g6f77f65b4e-goog In-Reply-To: <20200920004930.2108887-1-sjg@chromium.org> References: <20200920004930.2108887-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean Some blobs need a larger alignment than the default. For example, ACPI tables often start at a 4KB boundary. Add support for this. Update the size of the test blob to allow these larger records. Signed-off-by: Simon Glass Signed-off-by: Simon Glass --- common/bloblist.c | 32 ++++++++++++++++++++------------ include/bloblist.h | 6 ++++-- test/bloblist.c | 42 +++++++++++++++++++++++++++++++++--------- 3 files changed, 57 insertions(+), 23 deletions(-) diff --git a/common/bloblist.c b/common/bloblist.c index 173f28d8ec9..33b58623807 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -83,18 +83,25 @@ static struct bloblist_rec *bloblist_findrec(uint tag) return NULL; } -static int bloblist_addrec(uint tag, int size, struct bloblist_rec **recp) +static int bloblist_addrec(uint tag, int size, int align, + struct bloblist_rec **recp) { struct bloblist_hdr *hdr = gd->bloblist; struct bloblist_rec *rec; int data_start, new_alloced; + if (!align) + align = BLOBLIST_ALIGN; + /* Figure out where the new data will start */ - data_start = hdr->alloced + sizeof(*rec); - data_start = ALIGN(data_start, BLOBLIST_ALIGN); + data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*rec); + + /* Align the address and then calculate the offset from ->alloced */ + data_start = ALIGN(data_start, align) - map_to_sysmem(hdr); /* Calculate the new allocated total */ - new_alloced = data_start + ALIGN(size, BLOBLIST_ALIGN); + new_alloced = data_start + ALIGN(size, align); + if (new_alloced >= hdr->size) { log(LOGC_BLOBLIST, LOGL_ERR, "Failed to allocate %x bytes size=%x, need size=%x\n", @@ -117,7 +124,8 @@ static int bloblist_addrec(uint tag, int size, struct bloblist_rec **recp) return 0; } -static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size) +static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size, + int align) { struct bloblist_rec *rec; @@ -130,7 +138,7 @@ static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size) } else { int ret; - ret = bloblist_addrec(tag, size, &rec); + ret = bloblist_addrec(tag, size, align, &rec); if (ret) return ret; } @@ -152,22 +160,22 @@ void *bloblist_find(uint tag, int size) return (void *)rec + rec->hdr_size; } -void *bloblist_add(uint tag, int size) +void *bloblist_add(uint tag, int size, int align) { struct bloblist_rec *rec; - if (bloblist_addrec(tag, size, &rec)) + if (bloblist_addrec(tag, size, align, &rec)) return NULL; return (void *)rec + rec->hdr_size; } -int bloblist_ensure_size(uint tag, int size, void **blobp) +int bloblist_ensure_size(uint tag, int size, int align, void **blobp) { struct bloblist_rec *rec; int ret; - ret = bloblist_ensurerec(tag, &rec, size); + ret = bloblist_ensurerec(tag, &rec, size, align); if (ret) return ret; *blobp = (void *)rec + rec->hdr_size; @@ -179,7 +187,7 @@ void *bloblist_ensure(uint tag, int size) { struct bloblist_rec *rec; - if (bloblist_ensurerec(tag, &rec, size)) + if (bloblist_ensurerec(tag, &rec, size, 0)) return NULL; return (void *)rec + rec->hdr_size; @@ -190,7 +198,7 @@ int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp) struct bloblist_rec *rec; int ret; - ret = bloblist_ensurerec(tag, &rec, *sizep); + ret = bloblist_ensurerec(tag, &rec, *sizep, 0); if (ret == -ESPIPE) *sizep = rec->size; else if (ret) diff --git a/include/bloblist.h b/include/bloblist.h index 57c0794793b..9ad5678aff8 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -124,10 +124,11 @@ void *bloblist_find(uint tag, int size); * * @tag: Tag to add (enum bloblist_tag_t) * @size: Size of the blob + * @align: Alignment of the blob (in bytes), 0 for default * @return pointer to the newly added block, or NULL if there is not enough * space for the blob */ -void *bloblist_add(uint tag, int size); +void *bloblist_add(uint tag, int size, int align); /** * bloblist_ensure_size() - Find or add a blob @@ -137,10 +138,11 @@ void *bloblist_add(uint tag, int size); * @tag: Tag to add (enum bloblist_tag_t) * @size: Size of the blob * @blobp: Returns a pointer to blob on success + * @align: Alignment of the blob (in bytes), 0 for default * @return 0 if OK, -ENOSPC if it is missing and could not be added due to lack * of space, or -ESPIPE it exists but has the wrong size */ -int bloblist_ensure_size(uint tag, int size, void **blobp); +int bloblist_ensure_size(uint tag, int size, int align, void **blobp); /** * bloblist_ensure() - Find or add a blob diff --git a/test/bloblist.c b/test/bloblist.c index 3493e681f39..004a4396171 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -25,10 +25,10 @@ enum { TEST_SIZE = 10, TEST_SIZE2 = 20, - TEST_SIZE_LARGE = 0xe0, + TEST_SIZE_LARGE = 0x3e0, TEST_ADDR = CONFIG_BLOBLIST_ADDR, - TEST_BLOBLIST_SIZE = 0x100, + TEST_BLOBLIST_SIZE = 0x400, ERASE_BYTE = '\xff', }; @@ -100,7 +100,7 @@ static int bloblist_test_blob(struct unit_test_state *uts) ut_asserteq(map_to_sysmem(hdr), TEST_ADDR); /* Add a record and check that we can find it */ - data = bloblist_add(TEST_TAG, TEST_SIZE); + data = bloblist_add(TEST_TAG, TEST_SIZE, 0); rec = (void *)(hdr + 1); ut_asserteq_addr(rec + 1, data); data = bloblist_find(TEST_TAG, TEST_SIZE); @@ -206,10 +206,10 @@ static int bloblist_test_checksum(struct unit_test_state *uts) hdr->chksum--; /* Make sure the checksum changes when we add blobs */ - data = bloblist_add(TEST_TAG, TEST_SIZE); + data = bloblist_add(TEST_TAG, TEST_SIZE, 0); ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); - data2 = bloblist_add(TEST_TAG2, TEST_SIZE2); + data2 = bloblist_add(TEST_TAG2, TEST_SIZE2, 0); ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); ut_assertok(bloblist_finish()); @@ -255,9 +255,9 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts) console_record_reset(); run_command("bloblist info", 0); ut_assert_nextline("base: %x", map_to_sysmem(hdr)); - ut_assert_nextline("size: 100 256 Bytes"); + ut_assert_nextline("size: 400 1 KiB"); ut_assert_nextline("alloced: 70 112 Bytes"); - ut_assert_nextline("free: 90 144 Bytes"); + ut_assert_nextline("free: 390 912 Bytes"); ut_assert_console_end(); gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD); @@ -298,6 +298,8 @@ BLOBLIST_TEST(bloblist_test_cmd_list, 0); static int bloblist_test_align(struct unit_test_state *uts) { struct bloblist_hdr *hdr; + ulong addr; + char *data; int i; /* At the start there should be no records */ @@ -305,14 +307,14 @@ static int bloblist_test_align(struct unit_test_state *uts) ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); - /* Check the alignment */ + /* Check the default alignment */ for (i = 0; i < 3; i++) { int size = i * 3; ulong addr; char *data; int j; - data = bloblist_add(i, size); + data = bloblist_add(i, size, 0); ut_assertnonnull(data); addr = map_to_sysmem(data); ut_asserteq(0, addr & (BLOBLIST_ALIGN - 1)); @@ -324,6 +326,28 @@ static int bloblist_test_align(struct unit_test_state *uts) ut_asserteq(ERASE_BYTE, data[j]); } + /* Check larger alignment */ + for (i = 0; i < 3; i++) { + int align = 32 << i; + + data = bloblist_add(3 + i, i * 4, align); + ut_assertnonnull(data); + addr = map_to_sysmem(data); + ut_asserteq(0, addr & (align - 1)); + } + + /* Check alignment with an bloblist starting on a smaller alignment */ + hdr = map_sysmem(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE); + memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE); + memset(hdr, '\0', sizeof(*hdr)); + ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE, + 0)); + + data = bloblist_add(1, 5, BLOBLIST_ALIGN * 2); + ut_assertnonnull(data); + addr = map_to_sysmem(data); + ut_asserteq(0, addr & (BLOBLIST_ALIGN * 2 - 1)); + return 0; } BLOBLIST_TEST(bloblist_test_align, 0);