summaryrefslogtreecommitdiff
path: root/util/cbfstool/fit.c
diff options
context:
space:
mode:
authorSol Boucher <solb@chromium.org>2015-05-06 14:44:40 -0700
committerStefan Reinauer <stefan.reinauer@coreboot.org>2015-05-26 02:30:21 +0200
commit32532ac92dd83d08e5d10de2d3a41fe3c9092e2c (patch)
tree140f1fad91503353b1292951789a2909c3124ee4 /util/cbfstool/fit.c
parent83070504125a8023a24cb87c3f3184d3ad9b1d20 (diff)
cbfstool: Make update-fit action work on new-style images
Because new images place the bootblock in a separate region from the primary CBFS, performing an update-fit operation requires reading an additional section and choosing a different destination for the write based on the image type. Since other actions are not affected by these requirements, the logic for the optional read and all writing is implemented in the cbfs_update_fit() function itself, rather than relying on the main() function for writing as the other actions do. Change-Id: I2024c59715120ecc3b9b158e007ebce75acff023 Signed-off-by: Sol Boucher <solb@chromium.org> Reviewed-on: http://review.coreboot.org/10137 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'util/cbfstool/fit.c')
-rw-r--r--util/cbfstool/fit.c54
1 files changed, 29 insertions, 25 deletions
diff --git a/util/cbfstool/fit.c b/util/cbfstool/fit.c
index 0a7bea5725..6039714456 100644
--- a/util/cbfstool/fit.c
+++ b/util/cbfstool/fit.c
@@ -18,13 +18,10 @@
*/
#include <stdint.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <stdio.h>
-#include "common.h"
-#include "cbfs.h"
-#include "cbfs_image.h"
#include "fit.h"
/* FIXME: This code assumes it is being executed on a little endian machine. */
@@ -69,9 +66,9 @@ struct microcode_entry {
int size;
};
-static inline void *rom_buffer_pointer(struct cbfs_image *image, int offset)
+static inline void *rom_buffer_pointer(struct buffer *buffer, int offset)
{
- return &image->buffer.data[offset];
+ return &buffer->data[offset];
}
static inline int fit_entry_size_bytes(struct fit_entry *entry)
@@ -104,9 +101,10 @@ static inline int fit_entry_type(struct fit_entry *entry)
* in the host address space at [4G - romsize -> 4G). It also assume all
* pointers have values within this address range.
*/
-static inline int ptr_to_offset(uint32_t theromsize, uint32_t host_ptr)
+static inline int ptr_to_offset(fit_offset_converter_t helper,
+ const struct buffer *region, uint32_t host_ptr)
{
- return (int)(theromsize + host_ptr);
+ return helper(region, -host_ptr);
}
/*
@@ -114,25 +112,28 @@ static inline int ptr_to_offset(uint32_t theromsize, uint32_t host_ptr)
* in the host address space at [4G - romsize -> 4G). It also assume all
* pointers have values within this address range.
*/
-static inline uint32_t offset_to_ptr(uint32_t theromsize, int offset)
+static inline uint32_t offset_to_ptr(fit_offset_converter_t helper,
+ const struct buffer *region, int offset)
{
- return -(theromsize - (uint32_t )offset);
+ return -helper(region, offset);
}
-static struct fit_table *locate_fit_table(struct cbfs_image *image)
+static struct fit_table *locate_fit_table(fit_offset_converter_t offset_helper,
+ struct buffer *buffer)
{
struct fit_table *table;
uint32_t *fit_pointer;
- fit_pointer = rom_buffer_pointer(image,
- ptr_to_offset(image->buffer.size, FIT_POINTER_LOCATION));
+ fit_pointer = rom_buffer_pointer(buffer,
+ ptr_to_offset(offset_helper, buffer,
+ FIT_POINTER_LOCATION));
/* Ensure pointer is below 4GiB and within 16MiB of 4GiB */
if (fit_pointer[1] != 0 || fit_pointer[0] < FIT_TABLE_LOWEST_ADDRESS)
return NULL;
- table = rom_buffer_pointer(image,
- ptr_to_offset(image->buffer.size, *fit_pointer));
+ table = rom_buffer_pointer(buffer,
+ ptr_to_offset(offset_helper, buffer, *fit_pointer));
/* Check that the address field has the proper signature. */
if (strncmp((const char *)&table->header.address, FIT_HEADER_ADDRESS,
@@ -168,9 +169,10 @@ static void update_fit_checksum(struct fit_table *fit)
fit->header.checksum = -result;
}
-static void add_microcodde_entries(struct cbfs_image *image,
- struct fit_table *fit,
- struct microcode_entry *mcus, int num_mcus)
+static void add_microcodde_entries(struct fit_table *fit,
+ const struct cbfs_image *image,
+ int num_mcus, struct microcode_entry *mcus,
+ fit_offset_converter_t offset_helper)
{
int i;
@@ -178,7 +180,8 @@ static void add_microcodde_entries(struct cbfs_image *image,
struct fit_entry *entry = &fit->entries[i];
struct microcode_entry *mcu = &mcus[i];
- entry->address = offset_to_ptr(image->buffer.size, mcu->offset);
+ entry->address = offset_to_ptr(offset_helper, &image->buffer,
+ mcu->offset);
fit_entry_update_size(entry, mcu->size);
entry->version = FIT_MICROCODE_VERSION;
entry->type_checksum_valid = FIT_TYPE_MICROCODE;
@@ -213,9 +216,9 @@ static int parse_microcode_blob(struct cbfs_image *image,
num_mcus = 0;
while (file_length > sizeof(struct microcode_header))
{
- struct microcode_header *mcu_header;
+ const struct microcode_header *mcu_header;
- mcu_header = rom_buffer_pointer(image, current_offset);
+ mcu_header = rom_buffer_pointer(&image->buffer, current_offset);
/* Quickly sanity check a prospective microcode update. */
if (mcu_header->total_size < sizeof(*mcu_header))
@@ -243,8 +246,9 @@ static int parse_microcode_blob(struct cbfs_image *image,
return 0;
}
-int fit_update_table(struct cbfs_image *image, int empty_entries,
- const char *microcode_blob_name)
+int fit_update_table(struct buffer *bootblock, struct cbfs_image *image,
+ const char *microcode_blob_name, int empty_entries,
+ fit_offset_converter_t offset_fn)
{
struct fit_table *fit;
struct cbfs_file *mcode_file;
@@ -252,7 +256,7 @@ int fit_update_table(struct cbfs_image *image, int empty_entries,
int ret = 0;
// struct rom_image image = { .rom = rom, .size = romsize, };
- fit = locate_fit_table(image);
+ fit = locate_fit_table(offset_fn, bootblock);
if (!fit) {
ERROR("FIT not found.\n");
@@ -279,7 +283,7 @@ int fit_update_table(struct cbfs_image *image, int empty_entries,
goto out;
}
- add_microcodde_entries(image, fit, mcus, empty_entries);
+ add_microcodde_entries(fit, image, empty_entries, mcus, offset_fn);
update_fit_checksum(fit);
out: