From c4a8c48b2f70d56c7c318f4ce24a467a1d708ef5 Mon Sep 17 00:00:00 2001
From: Marshall Dawson <marshalldawson3rd@gmail.com>
Date: Tue, 21 Jan 2020 17:17:59 -0700
Subject: util/amdfwtool: Clarify APOB NV requirements

Relocate the first size check.  This was automatically continuing
and not looking for the caller incorrectly passing a destination.

New information indicates that the APOB_NV should always be present
in the system.  Augment the missing size check to inferring whether
a missing size is valid, as in the case of older products, or truly
missing when it's needed.

Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com>
Change-Id: I51f5333de4392dec1478bd84563c053a508b9e9e
Reviewed-on: https://review.coreboot.org/c/coreboot/+/38690
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Martin Roth <martinroth@google.com>
---
 util/amdfwtool/amdfwtool.c | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

(limited to 'util/amdfwtool')

diff --git a/util/amdfwtool/amdfwtool.c b/util/amdfwtool/amdfwtool.c
index 379caaab5a..5bcc0a7d77 100644
--- a/util/amdfwtool/amdfwtool.c
+++ b/util/amdfwtool/amdfwtool.c
@@ -808,6 +808,17 @@ static int have_bios_tables(amd_bios_entry *table)
 	return 0;
 }
 
+static int find_bios_entry(amd_bios_type type)
+{
+	int i;
+
+	for (i = 0; amd_bios_table[i].type != AMD_BIOS_INVALID; i++) {
+		if (amd_bios_table[i].type == type)
+			return i;
+	}
+	return -1;
+}
+
 static void integrate_bios_firmwares(context *ctx,
 					bios_directory_table *biosdir,
 					bios_directory_table *biosdir2,
@@ -817,6 +828,7 @@ static void integrate_bios_firmwares(context *ctx,
 	ssize_t bytes;
 	unsigned int i, count;
 	int level;
+	int apob_idx;
 
 	/* This function can create a primary table, a secondary table, or a
 	 * flattened table which contains all applicable types.  These if-else
@@ -843,9 +855,6 @@ static void integrate_bios_firmwares(context *ctx,
 				fw_table[i].type != AMD_BIOS_L2_PTR &&
 				fw_table[i].type != AMD_BIOS_BIN))
 			continue;
-		/* APOB_NV needs a size, else no S3 and skip item */
-		if (fw_table[i].type == AMD_BIOS_APOB_NV && !fw_table[i].size)
-			continue;
 
 		/* BIOS Directory items may have additional requirements */
 
@@ -857,6 +866,19 @@ static void integrate_bios_firmwares(context *ctx,
 				exit(1);
 			}
 		}
+		/* APOB_NV needs a size, else no choice but to skip the item */
+		if (fw_table[i].type == AMD_BIOS_APOB_NV && !fw_table[i].size) {
+			/* Attempt to determine whether this is an error */
+			apob_idx = find_bios_entry(AMD_BIOS_APOB);
+			if (apob_idx < 0 || !fw_table[apob_idx].dest) {
+				/* APOV NV not expected to be used */
+				continue;
+			} else {
+				printf("Error: APOB NV must have a size\n");
+				free(ctx->rom);
+				exit(1);
+			}
+		}
 
 		/* APOB_DATA needs destination */
 		if (fw_table[i].type == AMD_BIOS_APOB && !fw_table[i].dest) {
-- 
cgit v1.2.3