Writes a complete .fmd for the IFD layout (valid input for fmaptool). * coreboot replaces the SI_BIOS line with a top-aligned region and sub-layout. */
| 1104 | * coreboot replaces the SI_BIOS line with a top-aligned region and sub-layout. |
| 1105 | */ |
| 1106 | static void create_fmap_template(char *image, int size, const char *layout_fname) |
| 1107 | { |
| 1108 | const struct frba *frba = find_frba(image, size); |
| 1109 | if (!frba) |
| 1110 | exit(EXIT_FAILURE); |
| 1111 | |
| 1112 | int layout_fd = open(layout_fname, O_WRONLY | O_CREAT | O_TRUNC, 0644); |
| 1113 | if (layout_fd == -1) { |
| 1114 | perror("Could not open file"); |
| 1115 | exit(EXIT_FAILURE); |
| 1116 | } |
| 1117 | |
| 1118 | unsigned int flash_size = ifd_image_size(frba); |
| 1119 | char buf[LAYOUT_LINELEN]; |
| 1120 | |
| 1121 | snprintf(buf, LAYOUT_LINELEN, "FLASH 0x%X {\n", flash_size); |
| 1122 | if (write(layout_fd, buf, strlen(buf)) < 0) { |
| 1123 | perror("Could not write to file"); |
| 1124 | exit(EXIT_FAILURE); |
| 1125 | } |
| 1126 | |
| 1127 | /* fmaptool requires regions in .fmd to be sorted by base address. */ |
| 1128 | int count_regions = 0; |
| 1129 | struct region sorted_regions[MAX_REGIONS] = { 0 }; |
| 1130 | for (unsigned int i = 0; i < max_regions; i++) { |
| 1131 | struct region region = get_region(frba, i); |
| 1132 | |
| 1133 | /* A region limit of 0 is an indicator of an unused region |
| 1134 | * A region base of 7FFFh is an indicator of a reserved region |
| 1135 | */ |
| 1136 | if (region.limit == 0 || region.base == 0x07FFF000) |
| 1137 | continue; |
| 1138 | |
| 1139 | /* Is there an FMAP equivalent? IFD reserved regions are usually thrown out |
| 1140 | * of the FMAP here |
| 1141 | */ |
| 1142 | if (!region_names[region.type].fmapname) { |
| 1143 | printf("Skip IFD region: %s\n", region_names[region.type].pretty); |
| 1144 | continue; |
| 1145 | } |
| 1146 | |
| 1147 | sorted_regions[count_regions] = region; |
| 1148 | /* insertion sort by base */ |
| 1149 | for (int j = count_regions - 1; j >= 0; j--) { |
| 1150 | if (sorted_regions[j].base > sorted_regions[j + 1].base) { |
| 1151 | struct region tmp = sorted_regions[j]; |
| 1152 | sorted_regions[j] = sorted_regions[j + 1]; |
| 1153 | sorted_regions[j + 1] = tmp; |
| 1154 | } |
| 1155 | } |
| 1156 | count_regions++; |
| 1157 | } |
| 1158 | |
| 1159 | for (int i = 0; i < count_regions; i++) { |
| 1160 | struct region region = sorted_regions[i]; |
| 1161 | |
| 1162 | snprintf(buf, LAYOUT_LINELEN, "\t%s@0x%X 0x%X\n", |
| 1163 | region_names[region.type].fmapname, region.base, region.size); |
no test coverage detected