| 265 | } |
| 266 | |
| 267 | static int |
| 268 | parse_microcode_blob(struct cbfs_image *image, |
| 269 | const char *blob_name, |
| 270 | size_t *mcus_found, |
| 271 | struct microcode_entry *mcus, |
| 272 | const size_t max_fit_entries) |
| 273 | { |
| 274 | size_t num_mcus; |
| 275 | uint32_t current_offset; |
| 276 | uint32_t file_length; |
| 277 | struct cbfs_file *mcode_file; |
| 278 | |
| 279 | mcode_file = cbfs_get_entry(image, blob_name); |
| 280 | if (!mcode_file) { |
| 281 | ERROR("Couldn't find microcode blob.\n"); |
| 282 | return 1; |
| 283 | } |
| 284 | |
| 285 | fit_location_from_cbfs_header(¤t_offset, &file_length, |
| 286 | mcode_file); |
| 287 | current_offset += cbfs_get_entry_addr(image, mcode_file); |
| 288 | |
| 289 | num_mcus = 0; |
| 290 | while (file_length > sizeof(struct microcode_header)) { |
| 291 | const struct microcode_header *mcu_header; |
| 292 | |
| 293 | mcu_header = rom_buffer_pointer(&image->buffer, current_offset); |
| 294 | if (!mcu_header) { |
| 295 | ERROR("Couldn't parse microcode header.\n"); |
| 296 | return 1; |
| 297 | } |
| 298 | |
| 299 | /* Newer microcode updates include a size field, whereas older |
| 300 | * containers set it at 0 and are exactly 2048 bytes long */ |
| 301 | uint32_t total_size = mcu_header->total_size ?: 2048; |
| 302 | |
| 303 | /* Quickly sanity check a prospective microcode update. */ |
| 304 | if (total_size < sizeof(*mcu_header) || |
| 305 | total_size > file_length) |
| 306 | break; |
| 307 | |
| 308 | if (num_mcus == max_fit_entries) { |
| 309 | ERROR("Maximum of FIT entries reached.\n"); |
| 310 | return 1; |
| 311 | } |
| 312 | |
| 313 | /* FIXME: Should the checksum be validated? */ |
| 314 | mcus[num_mcus].offset = current_offset; |
| 315 | mcus[num_mcus].size = total_size; |
| 316 | |
| 317 | /* Proceed to next payload. */ |
| 318 | current_offset += mcus[num_mcus].size; |
| 319 | file_length -= mcus[num_mcus].size; |
| 320 | num_mcus++; |
| 321 | if (file_length < sizeof(struct microcode_header)) |
| 322 | break; |
| 323 | } |
| 324 |
no test coverage detected