aboutsummaryrefslogtreecommitdiff
path: root/src/commonlib/cbfs.c
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2016-08-19 15:24:54 -0700
committerJulius Werner <jwerner@chromium.org>2016-08-27 01:16:16 +0200
commit71885a49600db1df58060406c0bb8a5b976c554c (patch)
tree53ef1292e7659e99a43c33cf6f1dfa7a4f734eaa /src/commonlib/cbfs.c
parent2a1847ea125b4b867f435635173acb39c9d75292 (diff)
commonlib: cbfs: Add CBFS attribute support
This patch adds support for the CBFS attributes that were already introduced in cbfstool and libpayload. I'm only copy&pasting the header definitions needed for this once more. Really, we should be unifying the definitions (and possibly part of the code) from cbfstool with commonlib, but apparently that hadn't been done when this feature was introduced and I don't really have time to do it cleanly now. Also add a function to extract info from the compression attribute, which can then be used to run cbfs_load_and_decompress() on the file. Change-Id: I7b6463597757122cfe84f006c946a1658bb3acc6 Signed-off-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://review.coreboot.org/16271 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/commonlib/cbfs.c')
-rw-r--r--src/commonlib/cbfs.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/commonlib/cbfs.c b/src/commonlib/cbfs.c
index 56faf286ef..1db8d31acf 100644
--- a/src/commonlib/cbfs.c
+++ b/src/commonlib/cbfs.c
@@ -108,6 +108,54 @@ int cbfs_for_each_file(const struct region_device *cbfs,
return -1;
}
+size_t cbfs_for_each_attr(void *metadata, size_t metadata_size,
+ size_t last_offset)
+{
+ struct cbfs_file_attribute *attr;
+
+ if (!last_offset) {
+ struct cbfs_file *file = metadata;
+ size_t start_offset = read_be32(&file->attributes_offset);
+ if (start_offset <= sizeof(struct cbfs_file) ||
+ start_offset + sizeof(*attr) > metadata_size)
+ return 0;
+ return start_offset;
+ }
+
+ attr = metadata + last_offset;
+ size_t next_offset = last_offset + read_be32(&attr->len);
+
+ if (next_offset + sizeof(*attr) > metadata_size)
+ return 0;
+ return next_offset;
+}
+
+int cbfsf_decompression_info(struct cbfsf *fh, uint32_t *algo, size_t *size)
+{
+ size_t metadata_size = region_device_sz(&fh->metadata);
+ void *metadata = rdev_mmap_full(&fh->metadata);
+ size_t offs = 0;
+
+ if (!metadata)
+ return -1;
+
+ while ((offs = cbfs_for_each_attr(metadata, metadata_size, offs))) {
+ struct cbfs_file_attr_compression *attr = metadata + offs;
+ if (read_be32(&attr->tag) != CBFS_FILE_ATTR_TAG_COMPRESSION)
+ continue;
+
+ *algo = read_be32(&attr->compression);
+ *size = read_be32(&attr->decompressed_size);
+ rdev_munmap(&fh->metadata, metadata);
+ return 0;
+ }
+
+ *algo = CBFS_COMPRESS_NONE;
+ *size = region_device_sz(&fh->data);
+ rdev_munmap(&fh->metadata, metadata);
+ return 0;
+}
+
static int cbfsf_file_type(struct cbfsf *fh, uint32_t *ftype)
{
const size_t sz = sizeof(*ftype);