aboutsummaryrefslogtreecommitdiff
path: root/common/bloblist.c
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2020-09-19 18:49:28 -0600
committerSimon Glass <sjg@chromium.org>2020-10-06 09:07:54 -0600
commit751b7c79634003b4cb326b79e80202ea45b75fc8 (patch)
tree2eaf7f16494841e8588ff6409255a09e339f7a19 /common/bloblist.c
parentcdd4e30dfcaba706120df340c0c8757d56e48b7a (diff)
downloadu-boot-751b7c79634003b4cb326b79e80202ea45b75fc8.zip
u-boot-751b7c79634003b4cb326b79e80202ea45b75fc8.tar.gz
u-boot-751b7c79634003b4cb326b79e80202ea45b75fc8.tar.bz2
bloblist: Tidy up the data alignment
The intention which bloblists is that each blob's data is aligned in memory. At present it is only the headers that are aligned. Update the code to correct this and add a little more documentation. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'common/bloblist.c')
-rw-r--r--common/bloblist.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/common/bloblist.c b/common/bloblist.c
index c86ea02..173f28d 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -11,6 +11,20 @@
#include <spl.h>
#include <u-boot/crc.h>
+/*
+ * A bloblist is a single contiguous chunk of memory with a header
+ * (struct bloblist_hdr) and a number of blobs in it.
+ *
+ * Each blob starts on a BLOBLIST_ALIGN boundary relative to the start of the
+ * bloblist and consists of a struct bloblist_rec, some padding to the required
+ * alignment for the blog and then the actual data. The padding ensures that the
+ * start address of the data in each blob is aligned as required. Note that
+ * each blob's *data* is aligned to BLOBLIST_ALIGN regardless of the alignment
+ * of the bloblist itself or the blob header.
+ *
+ * So far, only BLOBLIST_ALIGN alignment is supported.
+ */
+
DECLARE_GLOBAL_DATA_PTR;
static const char *const tag_name[] = {
@@ -73,9 +87,14 @@ static int bloblist_addrec(uint tag, int size, struct bloblist_rec **recp)
{
struct bloblist_hdr *hdr = gd->bloblist;
struct bloblist_rec *rec;
- int new_alloced;
+ int data_start, new_alloced;
+
+ /* Figure out where the new data will start */
+ data_start = hdr->alloced + sizeof(*rec);
+ data_start = ALIGN(data_start, BLOBLIST_ALIGN);
- new_alloced = hdr->alloced + sizeof(*rec) + ALIGN(size, BLOBLIST_ALIGN);
+ /* Calculate the new allocated total */
+ new_alloced = data_start + ALIGN(size, BLOBLIST_ALIGN);
if (new_alloced >= hdr->size) {
log(LOGC_BLOBLIST, LOGL_ERR,
"Failed to allocate %x bytes size=%x, need size=%x\n",
@@ -83,15 +102,16 @@ static int bloblist_addrec(uint tag, int size, struct bloblist_rec **recp)
return log_msg_ret("bloblist add", -ENOSPC);
}
rec = (void *)hdr + hdr->alloced;
- hdr->alloced = new_alloced;
rec->tag = tag;
- rec->hdr_size = sizeof(*rec);
+ rec->hdr_size = data_start - hdr->alloced;
rec->size = size;
rec->spare = 0;
/* Zero the record data */
- memset(rec + 1, '\0', rec->size);
+ memset((void *)rec + rec->hdr_size, '\0', rec->size);
+
+ hdr->alloced = new_alloced;
*recp = rec;
return 0;
@@ -139,7 +159,7 @@ void *bloblist_add(uint tag, int size)
if (bloblist_addrec(tag, size, &rec))
return NULL;
- return rec + 1;
+ return (void *)rec + rec->hdr_size;
}
int bloblist_ensure_size(uint tag, int size, void **blobp)