summaryrefslogtreecommitdiff
path: root/util/cbfstool
diff options
context:
space:
mode:
Diffstat (limited to 'util/cbfstool')
-rw-r--r--util/cbfstool/cbfstool.c170
1 files changed, 93 insertions, 77 deletions
diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c
index d26c418612..2dcc9d1cb6 100644
--- a/util/cbfstool/cbfstool.c
+++ b/util/cbfstool/cbfstool.c
@@ -317,28 +317,68 @@ struct mmap_window {
struct region host_space;
};
-enum mmap_window_type {
- X86_DEFAULT_DECODE_WINDOW, /* Decode window just below 4G boundary */
- X86_EXTENDED_DECODE_WINDOW, /* Extended decode window for mapping greater than 16MiB
- flash */
- MMAP_MAX_WINDOWS,
-};
+/* Should be enough for now */
+#define MMAP_MAX_WINDOWS 3
/* Table of all the decode windows supported by the platform. */
+static int mmap_window_table_size;
static struct mmap_window mmap_window_table[MMAP_MAX_WINDOWS];
-static void add_mmap_window(enum mmap_window_type idx, size_t flash_offset, size_t host_offset,
+static void add_mmap_window(size_t flash_offset, size_t host_offset,
size_t window_size)
{
- if (idx >= MMAP_MAX_WINDOWS) {
- ERROR("Incorrect mmap window index(%d)\n", idx);
+ if (mmap_window_table_size >= MMAP_MAX_WINDOWS) {
+ ERROR("Too many memory map windows\n");
return;
}
- mmap_window_table[idx].flash_space.offset = flash_offset;
- mmap_window_table[idx].host_space.offset = host_offset;
- mmap_window_table[idx].flash_space.size = window_size;
- mmap_window_table[idx].host_space.size = window_size;
+ mmap_window_table[mmap_window_table_size].flash_space.offset = flash_offset;
+ mmap_window_table[mmap_window_table_size].host_space.offset = host_offset;
+ mmap_window_table[mmap_window_table_size].flash_space.size = window_size;
+ mmap_window_table[mmap_window_table_size].host_space.size = window_size;
+ mmap_window_table_size++;
+}
+
+
+static int decode_mmap_arg(char *optarg)
+{
+ if (optarg == NULL)
+ return 1;
+
+ union {
+ unsigned long int array[3];
+ struct {
+ unsigned long int flash_base;
+ unsigned long int mmap_base;
+ unsigned long int mmap_size;
+ };
+ } mmap_args;
+ char *suffix = NULL;
+ char *substring = strtok(optarg, ":");
+ for (size_t i = 0; i < ARRAY_SIZE(mmap_args.array); i++) {
+ if (!substring) {
+ ERROR("Invalid mmap arguments '%s'.\n",
+ optarg);
+ return 1;
+ }
+ mmap_args.array[i] = strtol(substring, &suffix, 0);
+ if (suffix && *suffix) {
+ ERROR("Invalid mmap arguments '%s'.\n",
+ optarg);
+ return 1;
+ }
+ substring = strtok(NULL, ":");
+ }
+
+ if (substring != NULL) {
+ ERROR("Invalid argument, too many substrings '%s'.\n",
+ optarg);
+
+ return 1;
+ }
+
+ add_mmap_window(mmap_args.flash_base, mmap_args.mmap_base, mmap_args.mmap_size);
+ return 0;
}
#define DEFAULT_DECODE_WINDOW_TOP (4ULL * GiB)
@@ -351,57 +391,45 @@ static bool create_mmap_windows(void)
if (done)
return done;
- const size_t image_size = partitioned_file_total_size(param.image_file);
- const size_t std_window_size = MIN(DEFAULT_DECODE_WINDOW_MAX_SIZE, image_size);
- const size_t std_window_flash_offset = image_size - std_window_size;
+ // No memory map provided, use a default one
+ if (mmap_window_table_size == 0) {
+ const size_t image_size = partitioned_file_total_size(param.image_file);
+ printf("Image SIZE %lu\n", image_size);
+ const size_t std_window_size = MIN(DEFAULT_DECODE_WINDOW_MAX_SIZE, image_size);
+ const size_t std_window_flash_offset = image_size - std_window_size;
- /*
- * Default decode window lives just below 4G boundary in host space and maps up to a
- * maximum of 16MiB. If the window is smaller than 16MiB, the SPI flash window is mapped
- * at the top of the host window just below 4G.
- */
- add_mmap_window(X86_DEFAULT_DECODE_WINDOW, std_window_flash_offset,
- DEFAULT_DECODE_WINDOW_TOP - std_window_size, std_window_size);
-
- if (param.ext_win_size && (image_size > DEFAULT_DECODE_WINDOW_MAX_SIZE)) {
/*
- * If the platform supports extended window and the SPI flash size is greater
- * than 16MiB, then create a mapping for the extended window as well.
- * The assumptions here are:
- * 1. Top 16MiB is still decoded in the fixed decode window just below 4G
- * boundary.
- * 2. Rest of the SPI flash below the top 16MiB is mapped at the top of extended
- * window. Even though the platform might support a larger extended window, the
- * SPI flash part used by the mainboard might not be large enough to be mapped
- * in the entire window. In such cases, the mapping is assumed to be in the top
- * part of the extended window with the bottom part remaining unused.
- *
- * Example:
- * ext_win_base = 0xF8000000
- * ext_win_size = 32 * MiB
- * ext_win_limit = ext_win_base + ext_win_size - 1 = 0xF9FFFFFF
- *
- * If SPI flash is 32MiB, then top 16MiB is mapped from 0xFF000000 - 0xFFFFFFFF
- * whereas the bottom 16MiB is mapped from 0xF9000000 - 0xF9FFFFFF. The extended
- * window 0xF8000000 - 0xF8FFFFFF remains unused.
+ * Default decode window lives just below 4G boundary in host space and maps up to a
+ * maximum of 16MiB. If the window is smaller than 16MiB, the SPI flash window is mapped
+ * at the top of the host window just below 4G.
*/
- const size_t ext_window_mapped_size = MIN(param.ext_win_size,
- image_size - std_window_size);
- const size_t ext_window_top = param.ext_win_base + param.ext_win_size;
- add_mmap_window(X86_EXTENDED_DECODE_WINDOW,
- std_window_flash_offset - ext_window_mapped_size,
- ext_window_top - ext_window_mapped_size,
- ext_window_mapped_size);
-
- if (region_overlap(&mmap_window_table[X86_EXTENDED_DECODE_WINDOW].host_space,
- &mmap_window_table[X86_DEFAULT_DECODE_WINDOW].host_space)) {
- const struct region *ext_region;
-
- ext_region = &mmap_window_table[X86_EXTENDED_DECODE_WINDOW].host_space;
- ERROR("Extended window(base=0x%zx, limit=0x%zx) overlaps with default window!\n",
- region_offset(ext_region), region_end(ext_region));
-
- return false;
+ add_mmap_window(std_window_flash_offset, DEFAULT_DECODE_WINDOW_TOP - std_window_size, std_window_size);
+ } else {
+ /*
+ * Check provided memory map
+ */
+ for (int i = 0; i < mmap_window_table_size; i++) {
+ for (int j = i + 1; j < mmap_window_table_size; j++) {
+ if (region_overlap(&mmap_window_table[i].flash_space,
+ &mmap_window_table[j].flash_space)) {
+ ERROR("Flash space windows (base=0x%zx, limit=0x%zx) and (base=0x%zx, limit=0x%zx) overlap!\n",
+ region_offset(&mmap_window_table[i].flash_space),
+ region_end(&mmap_window_table[i].flash_space),
+ region_offset(&mmap_window_table[j].flash_space),
+ region_end(&mmap_window_table[j].flash_space));
+ return false;
+ }
+
+ if (region_overlap(&mmap_window_table[i].host_space,
+ &mmap_window_table[j].host_space)) {
+ ERROR("Host space windows (base=0x%zx, limit=0x%zx) and (base=0x%zx, limit=0x%zx) overlap!\n",
+ region_offset(&mmap_window_table[i].flash_space),
+ region_end(&mmap_window_table[i].flash_space),
+ region_offset(&mmap_window_table[j].flash_space),
+ region_end(&mmap_window_table[j].flash_space));
+ return false;
+ }
+ }
}
}
@@ -1777,8 +1805,7 @@ enum {
/* begin after ASCII characters */
LONGOPT_START = 256,
LONGOPT_IBB = LONGOPT_START,
- LONGOPT_EXT_WIN_BASE,
- LONGOPT_EXT_WIN_SIZE,
+ LONGOPT_MMAP,
LONGOPT_END,
};
@@ -1820,8 +1847,7 @@ static struct option long_options[] = {
{"mach-parseable",no_argument, 0, 'k' },
{"unprocessed", no_argument, 0, 'U' },
{"ibb", no_argument, 0, LONGOPT_IBB },
- {"ext-win-base", required_argument, 0, LONGOPT_EXT_WIN_BASE },
- {"ext-win-size", required_argument, 0, LONGOPT_EXT_WIN_SIZE },
+ {"mmap", required_argument, 0, LONGOPT_MMAP },
{NULL, 0, 0, 0 }
};
@@ -2262,19 +2288,9 @@ int main(int argc, char **argv)
case LONGOPT_IBB:
param.ibb = true;
break;
- case LONGOPT_EXT_WIN_BASE:
- param.ext_win_base = strtoul(optarg, &suffix, 0);
- if (!*optarg || (suffix && *suffix)) {
- ERROR("Invalid ext window base '%s'.\n", optarg);
- return 1;
- }
- break;
- case LONGOPT_EXT_WIN_SIZE:
- param.ext_win_size = strtoul(optarg, &suffix, 0);
- if (!*optarg || (suffix && *suffix)) {
- ERROR("Invalid ext window size '%s'.\n", optarg);
+ case LONGOPT_MMAP:
+ if (decode_mmap_arg(optarg))
return 1;
- }
break;
case 'h':
case '?':