util/cse_fpt: Add a new tool for managing Intel CSE FPT binaries
This change adds a new tool `cse_fpt` which can be used to print and dump CSE partitions in Flash Partition Table (FPT) format. BUG=b:189167923 Change-Id: I93c8d33e9baa327cbdab918a14f2f7a039953be6 Signed-off-by: Furquan Shaikh <furquan@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/55259 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
This commit is contained in:
3
util/cbfstool/fpt_formats/Makefile.inc
Normal file
3
util/cbfstool/fpt_formats/Makefile.inc
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
fpt_formats_obj += fpt_hdr_20.o
|
||||
fpt_formats_obj += fpt_hdr_21.o
|
106
util/cbfstool/fpt_formats/fpt_hdr_20.c
Normal file
106
util/cbfstool/fpt_formats/fpt_hdr_20.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/* CSE FPT header version 0x20 */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "cse_fpt.h"
|
||||
|
||||
struct fpt_hdr {
|
||||
uint8_t marker[4]; /* FPT_MARKER */
|
||||
uint32_t num_entries;
|
||||
uint8_t hdr_version; /* FPT_HDR_VERSION_20 */
|
||||
uint8_t entry_version; /* FPT_ENTRY_VERSION */
|
||||
uint8_t hdr_length;
|
||||
uint8_t hdr_checksum;
|
||||
uint8_t rsvd[20];
|
||||
} __packed;
|
||||
|
||||
static bool match_version(struct buffer *buff)
|
||||
{
|
||||
const uint8_t *data = buffer_get(buff);
|
||||
uint8_t version = read_at_le8(data, offsetof(struct fpt_hdr, hdr_version));
|
||||
|
||||
return version == FPT_HDR_VERSION_20;
|
||||
}
|
||||
|
||||
static bool validate_fpt_hdr(const struct fpt_hdr *h)
|
||||
{
|
||||
if (memcmp(h->marker, FPT_MARKER, sizeof(h->marker))) {
|
||||
ERROR("Invalid FPT header marker!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (h->hdr_version != FPT_HDR_VERSION_20) {
|
||||
ERROR("Invalid FPT header version(0x%x)!\n", h->hdr_version);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (h->entry_version != FPT_ENTRY_VERSION) {
|
||||
ERROR("Invalid FPT entry version(0x%x)!\n", h->entry_version);
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t *data = (const uint8_t *)h;
|
||||
uint8_t checksum = 0;
|
||||
|
||||
for (size_t i = 0; i < sizeof(*h); i++)
|
||||
checksum += data[i];
|
||||
|
||||
if (checksum != 0) {
|
||||
ERROR("Invalid checksum (0x%x)!\n", h->hdr_checksum);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static fpt_hdr_ptr read_fpt_hdr(struct buffer *buff)
|
||||
{
|
||||
struct fpt_hdr *h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return NULL;
|
||||
|
||||
READ_MEMBER(buff, h->marker);
|
||||
READ_MEMBER(buff, h->num_entries);
|
||||
READ_MEMBER(buff, h->hdr_version);
|
||||
READ_MEMBER(buff, h->entry_version);
|
||||
READ_MEMBER(buff, h->hdr_length);
|
||||
READ_MEMBER(buff, h->hdr_checksum);
|
||||
READ_MEMBER(buff, h->rsvd);
|
||||
|
||||
if (!validate_fpt_hdr(h)) {
|
||||
free(h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static void print_fpt_hdr(const fpt_hdr_ptr ptr)
|
||||
{
|
||||
struct fpt_hdr *h = ptr;
|
||||
|
||||
printf(" * FPT header\n");
|
||||
printf("%-25s: %.4s\n", "Marker", h->marker);
|
||||
printf("%-25s: %d\n", "Number of entries", h->num_entries);
|
||||
printf("%-25s: 0x%x\n", "Header version", h->hdr_version);
|
||||
printf("%-25s: 0x%x\n", "Entry version", h->entry_version);
|
||||
printf("%-25s: %d\n", "Header length", h->hdr_length);
|
||||
printf("%-25s: 0x%x\n", "Header checksum", h->hdr_checksum);
|
||||
}
|
||||
|
||||
static size_t get_entry_count(const fpt_hdr_ptr ptr)
|
||||
{
|
||||
struct fpt_hdr *h = ptr;
|
||||
|
||||
return h->num_entries;
|
||||
}
|
||||
|
||||
const struct fpt_hdr_ops fpt_hdr_20_ops = {
|
||||
.match_version = match_version,
|
||||
|
||||
.read = read_fpt_hdr,
|
||||
.print = print_fpt_hdr,
|
||||
|
||||
.get_entry_count = get_entry_count,
|
||||
};
|
114
util/cbfstool/fpt_formats/fpt_hdr_21.c
Normal file
114
util/cbfstool/fpt_formats/fpt_hdr_21.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/* CSE FPT header version 0x21 */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "cse_fpt.h"
|
||||
|
||||
struct fpt_hdr {
|
||||
uint8_t marker[4]; /* FPT_MARKER */
|
||||
uint32_t num_entries;
|
||||
uint8_t hdr_version; /* FPT_HDR_VERSION_21 */
|
||||
uint8_t entry_version; /* FPT_ENTRY_VERSION */
|
||||
uint8_t hdr_length;
|
||||
uint8_t redundancy;
|
||||
uint8_t reserved[8];
|
||||
uint32_t checksum;
|
||||
struct {
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
uint16_t build;
|
||||
uint16_t hotfix;
|
||||
} fit_tool_version;
|
||||
} __packed;
|
||||
|
||||
static bool match_version(struct buffer *buff)
|
||||
{
|
||||
const uint8_t *data = buffer_get(buff);
|
||||
uint8_t version = read_at_le8(data, offsetof(struct fpt_hdr, hdr_version));
|
||||
|
||||
return version == FPT_HDR_VERSION_21;
|
||||
}
|
||||
|
||||
static bool validate_fpt_hdr(const struct fpt_hdr *h)
|
||||
{
|
||||
if (memcmp(h->marker, FPT_MARKER, sizeof(h->marker))) {
|
||||
ERROR("Invalid FPT header marker!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (h->hdr_version != FPT_HDR_VERSION_21) {
|
||||
ERROR("Invalid FPT header version(0x%x)!\n", h->hdr_version);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (h->entry_version != FPT_ENTRY_VERSION) {
|
||||
ERROR("Invalid FPT entry version(0x%x)!\n", h->entry_version);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static fpt_hdr_ptr read_fpt_hdr(struct buffer *buff)
|
||||
{
|
||||
struct fpt_hdr *h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return NULL;
|
||||
|
||||
READ_MEMBER(buff, h->marker);
|
||||
READ_MEMBER(buff, h->num_entries);
|
||||
READ_MEMBER(buff, h->hdr_version);
|
||||
READ_MEMBER(buff, h->entry_version);
|
||||
READ_MEMBER(buff, h->hdr_length);
|
||||
READ_MEMBER(buff, h->redundancy);
|
||||
READ_MEMBER(buff, h->reserved);
|
||||
READ_MEMBER(buff, h->checksum);
|
||||
READ_MEMBER(buff, h->fit_tool_version);
|
||||
|
||||
if (!validate_fpt_hdr(h)) {
|
||||
free(h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static void print_fpt_hdr(const fpt_hdr_ptr ptr)
|
||||
{
|
||||
struct fpt_hdr *h = ptr;
|
||||
|
||||
printf(" * FPT header\n");
|
||||
printf("%-25s: %.4s\n", "Marker", h->marker);
|
||||
printf("%-25s: %d\n", "Number of entries", h->num_entries);
|
||||
printf("%-25s: 0x%x\n", "Header version", h->hdr_version);
|
||||
printf("%-25s: 0x%x\n", "Entry version", h->entry_version);
|
||||
printf("%-25s: %d\n", "Header length", h->hdr_length);
|
||||
printf("%-25s: 0x%x\n", "Redundancy", h->redundancy);
|
||||
printf("%-25s: ", "Reserved");
|
||||
for (size_t i = 0; i < ARRAY_SIZE(h->reserved); i++)
|
||||
printf("0x%x ", h->reserved[i]);
|
||||
printf("\n");
|
||||
printf("%-25s: 0x%x\n", "Checksum", h->checksum);
|
||||
printf("%-25s: %d.%d.%d.%d(%.2x.%.2x.%.2x.%.2x)\n", "FIT Tool Version",
|
||||
h->fit_tool_version.major, h->fit_tool_version.minor,
|
||||
h->fit_tool_version.build, h->fit_tool_version.hotfix,
|
||||
h->fit_tool_version.major, h->fit_tool_version.minor,
|
||||
h->fit_tool_version.build, h->fit_tool_version.hotfix);
|
||||
}
|
||||
|
||||
static size_t get_entry_count(const fpt_hdr_ptr ptr)
|
||||
{
|
||||
struct fpt_hdr *h = ptr;
|
||||
|
||||
return h->num_entries;
|
||||
}
|
||||
|
||||
const struct fpt_hdr_ops fpt_hdr_21_ops = {
|
||||
.match_version = match_version,
|
||||
|
||||
.read = read_fpt_hdr,
|
||||
.print = print_fpt_hdr,
|
||||
|
||||
.get_entry_count = get_entry_count,
|
||||
};
|
Reference in New Issue
Block a user