diff options
Diffstat (limited to 'util/cbfstool')
-rw-r--r-- | util/cbfstool/cbfstool.c | 170 |
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 '?': |