static struct bloblist_rec *bloblist_first_blob(struct bloblist_hdr *hdr)
{
- if (hdr->alloced <= hdr->hdr_size)
+ if (hdr->used_size <= hdr->hdr_size)
return NULL;
return (struct bloblist_rec *)((void *)hdr + hdr->hdr_size);
}
{
ulong offset = bloblist_blob_end_ofs(hdr, rec);
- if (offset >= hdr->alloced)
+ if (offset >= hdr->used_size)
return NULL;
return (struct bloblist_rec *)((void *)hdr + offset);
}
align_log2 = BLOBLIST_BLOB_ALIGN_LOG2;
/* Figure out where the new data will start */
- data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*rec);
+ data_start = map_to_sysmem(hdr) + hdr->used_size + sizeof(*rec);
- /* Align the address and then calculate the offset from ->alloced */
+ /* Align the address and then calculate the offset from used size */
aligned_start = ALIGN(data_start, 1U << align_log2) - data_start;
/* If we need to create a dummy record, create it */
return log_msg_ret("void", ret);
/* start the record after that */
- data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*vrec);
+ data_start = map_to_sysmem(hdr) + hdr->used_size + sizeof(*vrec);
}
/* Calculate the new allocated total */
new_alloced = data_start - map_to_sysmem(hdr) +
ALIGN(size, 1U << align_log2);
- if (new_alloced > hdr->size) {
- log_err("Failed to allocate %x bytes size=%x, need size=%x\n",
- size, hdr->size, new_alloced);
+ if (new_alloced > hdr->total_size) {
+ log_err("Failed to allocate %x bytes\n", size);
+ log_err("Used size=%x, total size=%x\n",
+ hdr->used_size, hdr->total_size);
return log_msg_ret("bloblist add", -ENOSPC);
}
- rec = (void *)hdr + hdr->alloced;
+ rec = (void *)hdr + hdr->used_size;
rec->tag_and_hdr_size = tag | sizeof(*rec) << BLOBLISTR_HDR_SIZE_SHIFT;
rec->size = size;
/* Zero the record data */
memset((void *)rec + rec_hdr_size(rec), '\0', rec->size);
- hdr->alloced = new_alloced;
+ hdr->used_size = new_alloced;
*recp = rec;
return 0;
int new_size)
{
int expand_by; /* Number of bytes to expand by (-ve to contract) */
- int new_alloced; /* New value for @hdr->alloced */
+ int new_alloced;
ulong next_ofs; /* Offset of the record after @rec */
expand_by = ALIGN(new_size - rec->size, BLOBLIST_BLOB_ALIGN);
- new_alloced = ALIGN(hdr->alloced + expand_by, BLOBLIST_BLOB_ALIGN);
+ new_alloced = ALIGN(hdr->used_size + expand_by, BLOBLIST_BLOB_ALIGN);
if (new_size < 0) {
log_debug("Attempt to shrink blob size below 0 (%x)\n",
new_size);
return log_msg_ret("size", -EINVAL);
}
- if (new_alloced > hdr->size) {
- log_err("Failed to allocate %x bytes size=%x, need size=%x\n",
- new_size, hdr->size, new_alloced);
+ if (new_alloced > hdr->total_size) {
+ log_err("Failed to allocate %x bytes\n", new_size);
+ log_err("Used size=%x, total size=%x\n",
+ hdr->used_size, hdr->total_size);
return log_msg_ret("alloc", -ENOSPC);
}
/* Move the following blobs up or down, if this is not the last */
next_ofs = bloblist_blob_end_ofs(hdr, rec);
- if (next_ofs != hdr->alloced) {
+ if (next_ofs != hdr->used_size) {
memmove((void *)hdr + next_ofs + expand_by,
(void *)hdr + next_ofs, new_alloced - next_ofs);
}
- hdr->alloced = new_alloced;
+ hdr->used_size = new_alloced;
/* Zero the new part of the blob */
if (expand_by > 0) {
{
u8 chksum;
- chksum = table_compute_checksum(hdr, hdr->alloced);
+ chksum = table_compute_checksum(hdr, hdr->used_size);
chksum += hdr->chksum;
return chksum;
hdr->hdr_size = sizeof(*hdr);
hdr->flags = flags;
hdr->magic = BLOBLIST_MAGIC;
- hdr->size = size;
- hdr->alloced = hdr->hdr_size;
+ hdr->used_size = hdr->hdr_size;
+ hdr->total_size = size;
hdr->chksum = 0;
gd->bloblist = hdr;
return log_msg_ret("Bad magic", -ENOENT);
if (hdr->version != BLOBLIST_VERSION)
return log_msg_ret("Bad version", -EPROTONOSUPPORT);
- if (size && hdr->size != size)
- return log_msg_ret("Bad size", -EFBIG);
+ if (!hdr->total_size || (size && hdr->total_size != size))
+ return log_msg_ret("Bad total size", -EFBIG);
+ if (hdr->used_size > hdr->total_size)
+ return log_msg_ret("Bad used size", -ENOENT);
+ if (hdr->hdr_size != sizeof(struct bloblist_hdr))
+ return log_msg_ret("Bad header size", -ENOENT);
+
chksum = bloblist_calc_chksum(hdr);
if (hdr->chksum != chksum) {
log_err("Checksum %x != %x\n", hdr->chksum, chksum);
struct bloblist_hdr *hdr = gd->bloblist;
hdr->chksum = bloblist_calc_chksum(hdr);
- log_debug("Finished bloblist size %lx at %lx\n", (ulong)hdr->size,
+ log_debug("Finished bloblist size %lx at %lx\n", (ulong)hdr->used_size,
(ulong)map_to_sysmem(hdr));
return 0;
{
struct bloblist_hdr *hdr = gd->bloblist;
- return hdr->size;
+ return hdr->used_size;
+}
+
+ulong bloblist_get_total_size(void)
+{
+ struct bloblist_hdr *hdr = gd->bloblist;
+
+ return hdr->total_size;
}
-void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp)
+void bloblist_get_stats(ulong *basep, ulong *tsizep, ulong *usizep)
{
struct bloblist_hdr *hdr = gd->bloblist;
*basep = map_to_sysmem(gd->bloblist);
- *sizep = hdr->size;
- *allocedp = hdr->alloced;
+ *tsizep = hdr->total_size;
+ *usizep = hdr->used_size;
}
static void show_value(const char *prompt, ulong value)
{
- printf("%s:%*s %-5lx ", prompt, 8 - (int)strlen(prompt), "", value);
+ printf("%s:%*s %-5lx ", prompt, 10 - (int)strlen(prompt), "", value);
print_size(value, "\n");
}
void bloblist_show_stats(void)
{
- ulong base, size, alloced;
+ ulong base, tsize, usize;
- bloblist_get_stats(&base, &size, &alloced);
- printf("base: %lx\n", base);
- show_value("size", size);
- show_value("alloced", alloced);
- show_value("free", size - alloced);
+ bloblist_get_stats(&base, &tsize, &usize);
+ printf("base: %lx\n", base);
+ show_value("total size", tsize);
+ show_value("used size", usize);
+ show_value("free", tsize - usize);
}
void bloblist_show_list(void)
memcpy(to, from, from_size);
hdr = to;
- hdr->size = to_size;
+ hdr->total_size = to_size;
}
int bloblist_init(void)
addr, ret);
} else {
/* Get the real size, if it is not what we expected */
- size = gd->bloblist->size;
+ size = gd->bloblist->total_size;
}
}
if (ret) {
* from the last.
*
* @magic: BLOBLIST_MAGIC
+ * @chksum: checksum for the entire bloblist allocated area. Since any of the
+ * blobs can be altered after being created, this checksum is only valid
+ * when the bloblist is finalized before jumping to the next stage of boot.
+ * This is the value needed to make all checksummed bytes sum to 0
* @version: BLOBLIST_VERSION
* @hdr_size: Size of this header, normally sizeof(struct bloblist_hdr). The
* first bloblist_rec starts at this offset from the start of the header
- * @flags: Space for BLOBLISTF... flags (none yet)
- * @size: Total size of the bloblist (non-zero if valid) including this header.
- * The bloblist extends for this many bytes from the start of this header.
- * When adding new records, the bloblist can grow up to this size.
- * @alloced: Total size allocated so far for this bloblist. This starts out as
+ * @align_log2: Power of two of the maximum alignment required by this list
+ * @used_size: Size allocated so far for this bloblist. This starts out as
* sizeof(bloblist_hdr) since we need at least that much space to store a
* valid bloblist
+ * @total_size: The number of total bytes that the bloblist can occupy.
+ * Any blob producer must check if there is sufficient space before adding
+ * a record to the bloblist.
+ * @flags: Space for BLOBLISTF... flags (none yet)
* @spare: Spare space (for future use)
- * @chksum: checksum for the entire bloblist allocated area. Since any of the
- * blobs can be altered after being created, this checksum is only valid
- * when the bloblist is finalised before jumping to the next stage of boot.
- * This is the value needed to make all checksummed bytes sum to 0
*/
struct bloblist_hdr {
u32 magic;
- u32 version;
- u32 hdr_size;
+ u8 chksum;
+ u8 version;
+ u8 hdr_size;
+ u8 align_log2;
+ u32 used_size;
+ u32 total_size;
u32 flags;
-
- u32 size;
- u32 alloced;
u32 spare;
- u32 chksum;
};
/**
* This returns useful information about the bloblist
*
* @basep: Returns base address of bloblist
- * @sizep: Returns the number of bytes used in the bloblist
- * @allocedp: Returns the total space allocated to the bloblist
+ * @tsizep: Returns the total number of bytes of the bloblist
+ * @usizep: Returns the number of used bytes of the bloblist
*/
-void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp);
+void bloblist_get_stats(ulong *basep, ulong *tsizep, ulong *usizep);
/**
* bloblist_get_base() - Get the base address of the bloblist
*/
ulong bloblist_get_size(void);
+/**
+ * bloblist_get_total_size() - Get the total size of the bloblist
+ *
+ * Return: the size in bytes
+ */
+ulong bloblist_get_total_size(void);
+
/**
* bloblist_show_stats() - Show information about the bloblist
*
ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR,
TEST_BLOBLIST_SIZE));
- ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10, 0));
+ ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0xc, 0));
ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
hdr = clear_bloblist();
ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
- ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_size());
+ ut_asserteq(sizeof(struct bloblist_hdr), bloblist_get_size());
+ ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_total_size());
ut_asserteq(TEST_ADDR, bloblist_get_base());
ut_asserteq(map_to_sysmem(hdr), TEST_ADDR);
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
hdr->flags++;
- hdr->size--;
+ hdr->total_size--;
ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
- hdr->size++;
+ hdr->total_size++;
hdr->spare++;
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
ut_silence_console(uts);
console_record_reset();
run_command("bloblist info", 0);
- ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr));
- ut_assert_nextline("size: 400 1 KiB");
- ut_assert_nextline("alloced: 58 88 Bytes");
- ut_assert_nextline("free: 3a8 936 Bytes");
+ ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr));
+ ut_assert_nextline("total size: 400 1 KiB");
+ ut_assert_nextline("used size: 50 80 Bytes");
+ ut_assert_nextline("free: 3b0 944 Bytes");
ut_assert_console_end();
ut_unsilence_console(uts);
ut_asserteq(sizeof(struct bloblist_hdr) +
sizeof(struct bloblist_rec) * 2 + small_size * 2,
- hdr->alloced);
+ hdr->used_size);
/* Resize the first one */
ut_assertok(bloblist_resize(TEST_TAG, small_size + 4));
ut_asserteq(sizeof(struct bloblist_hdr) +
sizeof(struct bloblist_rec) * 2 + small_size * 2 +
BLOBLIST_BLOB_ALIGN,
- hdr->alloced);
+ hdr->used_size);
return 0;
}
hdr = ptr;
ut_asserteq(sizeof(struct bloblist_hdr) +
sizeof(struct bloblist_rec) * 2 + small_size * 2,
- hdr->alloced);
+ hdr->used_size);
/* Resize the first one */
new_size = small_size - BLOBLIST_ALIGN - 4;
ut_asserteq(sizeof(struct bloblist_hdr) +
sizeof(struct bloblist_rec) * 2 + small_size * 2 -
BLOBLIST_ALIGN,
- hdr->alloced);
+ hdr->used_size);
return 0;
}
hdr = ptr;
ut_asserteq(sizeof(struct bloblist_hdr) +
sizeof(struct bloblist_rec) * 2 + small_size * 2,
- hdr->alloced);
+ hdr->used_size);
/* Resize the first one, to check the boundary conditions */
ut_asserteq(-EINVAL, bloblist_resize(TEST_TAG, -1));
- new_size = small_size + (hdr->size - hdr->alloced);
+ new_size = small_size + (hdr->total_size - hdr->used_size);
ut_asserteq(-ENOSPC, bloblist_resize(TEST_TAG, new_size + 1));
ut_assertok(bloblist_resize(TEST_TAG, new_size));
/* Check the byte after the last blob */
alloced_val = sizeof(struct bloblist_hdr) +
sizeof(struct bloblist_rec) * 2 + small_size * 2;
- ut_asserteq(alloced_val, hdr->alloced);
+ ut_asserteq(alloced_val, hdr->used_size);
ut_asserteq_ptr((void *)hdr + alloced_val, blob2 + small_size);
- ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->alloced));
+ ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->used_size));
/* Resize the second one, checking nothing changes */
ut_asserteq(0, bloblist_resize(TEST_TAG2, small_size + 4));
/* Check that the new top of the allocated blobs has not been touched */
alloced_val += BLOBLIST_BLOB_ALIGN;
- ut_asserteq(alloced_val, hdr->alloced);
- ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->alloced));
+ ut_asserteq(alloced_val, hdr->used_size);
+ ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->used_size));
return 0;
}