util/cbfstool: fix x86 execute-in-place semantics for all fmd regions

A previous patch [1] to make top-aligned addresses work within per
fmap regions caused a significant regression in the semantics of
adding programs that need to be execute-in-place (XIP) on x86
systems. Correct the regression by providing new function,
convert_to_from_absolute_top_aligned(), which top aligns against
the entire boot media.

[1] 9731119b cbfstool: make top-aligned address work per-region

Change-Id: I3b685abadcfc76dab8846eec21e9114a23577578
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://review.coreboot.org/14608
Tested-by: build bot (Jenkins)
Reviewed-by: Duncan Laurie <dlaurie@google.com>
Reviewed-by: Furquan Shaikh <furquan@google.com>
This commit is contained in:
Aaron Durbin 2016-05-04 16:07:15 -05:00
parent 6366d92803
commit ab00d779ed
1 changed files with 25 additions and 7 deletions

View File

@ -104,6 +104,21 @@ static bool region_is_modern_cbfs(const char *region)
CBFS_FILE_MAGIC, strlen(CBFS_FILE_MAGIC)); CBFS_FILE_MAGIC, strlen(CBFS_FILE_MAGIC));
} }
/*
* Converts between offsets from the start of the specified image region and
* "top-aligned" offsets from the top of the entire boot media. See comment
* below for convert_to_from_top_aligned() about forming addresses.
*/
static unsigned convert_to_from_absolute_top_aligned(
const struct buffer *region, unsigned offset)
{
assert(region);
size_t image_size = partitioned_file_total_size(param.image_file);
return image_size - region->offset - offset;
}
/* /*
* Converts between offsets from the start of the specified image region and * Converts between offsets from the start of the specified image region and
* "top-aligned" offsets from the top of the image region. Works in either * "top-aligned" offsets from the top of the image region. Works in either
@ -123,8 +138,7 @@ static unsigned convert_to_from_top_aligned(const struct buffer *region,
return region->size - offset; return region->size - offset;
} }
size_t image_size = partitioned_file_total_size(param.image_file); return convert_to_from_absolute_top_aligned(region, offset);
return image_size - region->offset - offset;
} }
static int do_cbfs_locate(int32_t *cbfs_addr, size_t metadata_size) static int do_cbfs_locate(int32_t *cbfs_addr, size_t metadata_size)
@ -462,8 +476,8 @@ static int cbfstool_convert_fsp(struct buffer *buffer,
/* Ensure the address is a memory mapped one. */ /* Ensure the address is a memory mapped one. */
if (!IS_TOP_ALIGNED_ADDRESS(address)) if (!IS_TOP_ALIGNED_ADDRESS(address))
address = -convert_to_from_top_aligned(param.image_region, address = -convert_to_from_absolute_top_aligned(
address); param.image_region, address);
/* Create a copy of the buffer to attempt relocation. */ /* Create a copy of the buffer to attempt relocation. */
if (buffer_create(&fsp, buffer_size(buffer), "fsp")) if (buffer_create(&fsp, buffer_size(buffer), "fsp"))
@ -498,9 +512,13 @@ static int cbfstool_convert_mkstage(struct buffer *buffer, uint32_t *offset,
return 1; return 1;
} }
/* Pass in a top aligned address. */ /*
address = -convert_to_from_top_aligned(param.image_region, * Ensure the address is a memory mapped one. This assumes
address); * x86 semantics about th boot media being directly mapped
* below 4GiB in the CPU address space.
**/
address = -convert_to_from_absolute_top_aligned(
param.image_region, address);
*offset = address; *offset = address;
ret = parse_elf_to_xip_stage(buffer, &output, offset, ret = parse_elf_to_xip_stage(buffer, &output, offset,