amdfwtool: Add universal cleanup function

Change-Id: Icc0cb79c06614aa2976d250dc73b8dc4040fd28c
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/73119
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Fred Reitberger <reitbergerfred@gmail.com>
This commit is contained in:
Zheng Bao 2023-02-19 13:02:52 +08:00 committed by Felix Held
parent 9ec60411ac
commit 7c5ad88887
1 changed files with 67 additions and 48 deletions

View File

@ -491,12 +491,55 @@ typedef struct _context {
#define SET_ADDR_MODE_BY_TABLE(table) \
SET_ADDR_MODE((table), (table)->header.additional_info_fields.address_mode)
static void free_psp_firmware_filenames(amd_fw_entry *fw_table)
{
amd_fw_entry *index;
for (index = fw_table; index->type != AMD_FW_INVALID; index++) {
if (index->filename &&
index->type != AMD_FW_VERSTAGE_SIG &&
index->type != AMD_FW_PSP_VERSTAGE &&
index->type != AMD_FW_SPL &&
index->type != AMD_FW_PSP_WHITELIST) {
free(index->filename);
index->filename = NULL;
}
}
}
static void free_bdt_firmware_filenames(amd_bios_entry *fw_table)
{
amd_bios_entry *index;
for (index = fw_table; index->type != AMD_BIOS_INVALID; index++) {
if (index->filename &&
index->type != AMD_BIOS_APCB &&
index->type != AMD_BIOS_BIN &&
index->type != AMD_BIOS_APCB_BK &&
index->type != AMD_BIOS_UCODE) {
free(index->filename);
index->filename = NULL;
}
}
}
static void amdfwtool_cleanup(context *ctx)
{
free(ctx->rom);
ctx->rom = NULL;
/* Free the filename. */
free_psp_firmware_filenames(amd_psp_fw_table);
free_bdt_firmware_filenames(amd_bios_table);
}
void assert_fw_entry(uint32_t count, uint32_t max, context *ctx)
{
if (count >= max) {
fprintf(stderr, "Error: BIOS entries (%d) exceeds max allowed items "
"(%d)\n", count, max);
free(ctx->rom);
amdfwtool_cleanup(ctx);
exit(1);
}
}
@ -506,7 +549,7 @@ static void set_current_pointer(context *ctx, uint32_t value)
if (ctx->current_pointer_saved != 0xFFFFFFFF &&
ctx->current_pointer_saved != ctx->current) {
fprintf(stderr, "Error: The pointer is changed elsewhere\n");
free(ctx->rom);
amdfwtool_cleanup(ctx);
exit(1);
}
@ -514,7 +557,7 @@ static void set_current_pointer(context *ctx, uint32_t value)
if (ctx->current > ctx->rom_size) {
fprintf(stderr, "Error: Packing data causes overflow\n");
free(ctx->rom);
amdfwtool_cleanup(ctx);
exit(1);
}
@ -609,6 +652,7 @@ static void fill_dir_header(void *directory, uint32_t count, uint32_t cookie, co
table_size = ctx->current - ctx->current_table;
if ((table_size % TABLE_ALIGNMENT) != 0) {
fprintf(stderr, "The PSP table size should be 4K aligned\n");
amdfwtool_cleanup(ctx);
exit(1);
}
dir->header.cookie = cookie;
@ -627,6 +671,7 @@ static void fill_dir_header(void *directory, uint32_t count, uint32_t cookie, co
table_size = ctx->current - ctx->current_table;
if ((table_size % TABLE_ALIGNMENT) != 0) {
fprintf(stderr, "The BIOS table size should be 4K aligned\n");
amdfwtool_cleanup(ctx);
exit(1);
}
bdir->header.cookie = cookie;
@ -897,7 +942,7 @@ static void integrate_firmwares(context *ctx,
bytes = copy_blob(BUFF_CURRENT(*ctx),
fw_table[i].filename, BUFF_ROOM(*ctx));
if (bytes < 0) {
free(ctx->rom);
amdfwtool_cleanup(ctx);
exit(1);
}
@ -929,35 +974,6 @@ static void dump_bdt_firmwares(amd_bios_entry *fw_table)
}
}
static void free_psp_firmware_filenames(amd_fw_entry *fw_table)
{
amd_fw_entry *index;
for (index = fw_table; index->type != AMD_FW_INVALID; index++) {
if (index->filename &&
index->type != AMD_FW_VERSTAGE_SIG &&
index->type != AMD_FW_PSP_VERSTAGE &&
index->type != AMD_FW_SPL &&
index->type != AMD_FW_PSP_WHITELIST) {
free(index->filename);
}
}
}
static void free_bdt_firmware_filenames(amd_bios_entry *fw_table)
{
amd_bios_entry *index;
for (index = fw_table; index->type != AMD_BIOS_INVALID; index++) {
if (index->filename &&
index->type != AMD_BIOS_APCB &&
index->type != AMD_BIOS_BIN &&
index->type != AMD_BIOS_APCB_BK &&
index->type != AMD_BIOS_UCODE)
free(index->filename);
}
}
static void write_or_fail(int fd, void *ptr, size_t size)
{
ssize_t written;
@ -1321,6 +1337,7 @@ static void integrate_psp_firmwares(context *ctx,
if (addr != ALIGN_UP(addr, ERASE_ALIGNMENT)) {
fprintf(stderr,
"Error: PSP NVRAM section not aligned with erase block size.\n\n");
amdfwtool_cleanup(ctx);
exit(1);
}
} else {
@ -1328,7 +1345,7 @@ static void integrate_psp_firmwares(context *ctx,
bytes = copy_blob(BUFF_CURRENT(*ctx),
fw_table[i].filename, BUFF_ROOM(*ctx));
if (bytes <= 0) {
free(ctx->rom);
amdfwtool_cleanup(ctx);
exit(1);
}
@ -1358,7 +1375,7 @@ static void integrate_psp_firmwares(context *ctx,
bytes = copy_blob(BUFF_CURRENT(*ctx),
fw_table[i].filename, BUFF_ROOM(*ctx));
if (bytes < 0) {
free(ctx->rom);
amdfwtool_cleanup(ctx);
exit(1);
}
pspdir->entries[count].addr = RUN_CURRENT(*ctx);
@ -1572,7 +1589,7 @@ static void integrate_bios_firmwares(context *ctx,
continue; /* APOB_NV not used */
if (fw_table[i].src && !fw_table[i].size) {
fprintf(stderr, "Error: APOB NV address provided, but no size\n");
free(ctx->rom);
amdfwtool_cleanup(ctx);
exit(1);
}
/* If the APOB isn't used, APOB_NV isn't used either */
@ -1584,7 +1601,7 @@ static void integrate_bios_firmwares(context *ctx,
/* APOB_DATA needs destination */
if (fw_table[i].type == AMD_BIOS_APOB && !fw_table[i].dest) {
fprintf(stderr, "Error: APOB destination not provided\n");
free(ctx->rom);
amdfwtool_cleanup(ctx);
exit(1);
}
@ -1594,12 +1611,12 @@ static void integrate_bios_firmwares(context *ctx,
if (fw_table[i].type == AMD_BIOS_BIN) {
if (!fw_table[i].dest || !fw_table[i].size) {
fprintf(stderr, "Error: BIOS binary destination and uncompressed size are required\n");
free(ctx->rom);
amdfwtool_cleanup(ctx);
exit(1);
}
if (!fw_table[i].filename && !fw_table[i].src) {
fprintf(stderr, "Error: BIOS binary assumed outside amdfw.rom but no source address given\n");
free(ctx->rom);
amdfwtool_cleanup(ctx);
exit(1);
}
}
@ -1680,7 +1697,7 @@ static void integrate_bios_firmwares(context *ctx,
bytes = copy_blob(BUFF_CURRENT(*ctx),
fw_table[i].filename, BUFF_ROOM(*ctx));
if (bytes <= 0) {
free(ctx->rom);
amdfwtool_cleanup(ctx);
exit(1);
}
@ -1703,7 +1720,7 @@ static void integrate_bios_firmwares(context *ctx,
bytes = copy_blob(BUFF_CURRENT(*ctx),
fw_table[i].filename, BUFF_ROOM(*ctx));
if (bytes <= 0) {
free(ctx->rom);
amdfwtool_cleanup(ctx);
exit(1);
}
@ -2028,7 +2045,7 @@ static int set_efs_table(uint8_t soc_id, amd_cb_config *cb_config,
return 0;
}
static ssize_t write_efs(char *output, embedded_firmware *amd_romsig)
static ssize_t write_efs(char *output, embedded_firmware *amd_romsig, context *ctx)
{
char efs_name[PATH_MAX], efs_tmp_name[PATH_MAX];
int ret;
@ -2042,21 +2059,25 @@ static ssize_t write_efs(char *output, embedded_firmware *amd_romsig)
if (ret < 0) {
fprintf(stderr, "Error %s forming EFS tmp file name: %d\n",
strerror(errno), ret);
amdfwtool_cleanup(ctx);
exit(1);
} else if ((unsigned int)ret >= sizeof(efs_tmp_name)) {
fprintf(stderr, "EFS File name %d > %zu\n", ret, sizeof(efs_tmp_name));
amdfwtool_cleanup(ctx);
exit(1);
}
fd = open(efs_tmp_name, O_RDWR | O_CREAT | O_TRUNC, 0666);
if (fd < 0) {
fprintf(stderr, "Error: Opening %s file: %s\n", efs_tmp_name, strerror(errno));
amdfwtool_cleanup(ctx);
exit(1);
}
bytes = write_from_buf_to_file(fd, amd_romsig, sizeof(*amd_romsig));
if (bytes != sizeof(*amd_romsig)) {
fprintf(stderr, "Error: Writing to file %s failed\n", efs_tmp_name);
amdfwtool_cleanup(ctx);
exit(1);
}
close(fd);
@ -2065,11 +2086,13 @@ static ssize_t write_efs(char *output, embedded_firmware *amd_romsig)
ret = snprintf(efs_name, sizeof(efs_name), "%s%s", output, EFS_FILE_SUFFIX);
if (ret < 0) {
fprintf(stderr, "Error %s forming EFS file name: %d\n", strerror(errno), ret);
amdfwtool_cleanup(ctx);
exit(1);
}
if (rename(efs_tmp_name, efs_name)) {
fprintf(stderr, "Error: renaming file %s to %s\n", efs_tmp_name, efs_name);
amdfwtool_cleanup(ctx);
exit(1);
}
@ -2637,10 +2660,6 @@ int main(int argc, char **argv)
}
}
/* Free the filename. */
free_psp_firmware_filenames(amd_psp_fw_table);
free_bdt_firmware_filenames(amd_bios_table);
targetfd = open(output, O_RDWR | O_CREAT | O_TRUNC, 0666);
if (targetfd >= 0) {
ssize_t bytes;
@ -2660,13 +2679,13 @@ int main(int argc, char **argv)
if (efs_location != body_location) {
ssize_t bytes;
bytes = write_efs(output, amd_romsig);
bytes = write_efs(output, amd_romsig, &ctx);
if (bytes != sizeof(*amd_romsig)) {
fprintf(stderr, "Error: Writing EFS\n");
retval = 1;
}
}
free(ctx.rom);
amdfwtool_cleanup(&ctx);
return retval;
}