summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/common/block/fast_spi/Makefile.inc34
-rw-r--r--util/cbfstool/cbfstool.c170
2 files changed, 126 insertions, 78 deletions
diff --git a/src/soc/intel/common/block/fast_spi/Makefile.inc b/src/soc/intel/common/block/fast_spi/Makefile.inc
index 1237000af0..cc65e1f23e 100644
--- a/src/soc/intel/common/block/fast_spi/Makefile.inc
+++ b/src/soc/intel/common/block/fast_spi/Makefile.inc
@@ -67,6 +67,38 @@ $(call add_intermediate, check-fmap-16mib-crossing, $(obj)/fmap_config.h)
done; \
exit $$fail
-CBFSTOOL_ADD_CMD_OPTIONS += --ext-win-base $(CONFIG_EXT_BIOS_WIN_BASE) --ext-win-size $(CONFIG_EXT_BIOS_WIN_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.
+#
+
+ifeq ($(call int-gt, $(CONFIG_ROM_SIZE) 0x1000000), 1)
+DEFAULT_WINDOW_SIZE=0x1000000
+DEFAULT_WINDOW_FLASH_BASE=$(call int-subtract, $(CONFIG_ROM_SIZE) $(DEFAULT_WINDOW_SIZE))
+DEFAULT_WINDOW_MMIO_BASE=0xff000000
+EXT_WINDOW_FLASH_BASE=0
+EXT_WINDOW_SIZE=$(DEFAULT_WINDOW_FLASH_BASE)
+EXT_WINDOW_MMIO_BASE=$(call int-subtract, $(call int-add, $(CONFIG_EXT_BIOS_WIN_BASE) $(CONFIG_EXT_BIOS_WIN_SIZE)) \
+ $(EXT_WINDOW_SIZE))
+CBFSTOOL_ADD_CMD_OPTIONS += --mmap $(DEFAULT_WINDOW_FLASH_BASE):$(DEFAULT_WINDOW_MMIO_BASE):$(DEFAULT_WINDOW_SIZE)
+CBFSTOOL_ADD_CMD_OPTIONS += --mmap $(EXT_WINDOW_FLASH_BASE):$(EXT_WINDOW_MMIO_BASE):$(EXT_WINDOW_SIZE)
+endif
+
endif # CONFIG_FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW
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 '?':