[Skiboot] [PATCH v2 03/12] core: add flash_subpart_info()

Claudio Carvalho cclaudio at linux.vnet.ibm.com
Wed Sep 28 18:10:53 AEST 2016


Currently, the CAPP lid has the TOC (4K) and one supartition (36K). For
secure boot we can either build one container for the TOC and another one for
the subpartition, or build one container for the whole CAPP partition.
We decided implement the second option.

The first option would require changes to the CAPP TOC layout in order to
correlate the TOC with the subpartitions. Besides that, the first option
also increases the boot time since we would need to verify and measure
the CAPP TOC.

This patch adds the flash_subpart_info function so the correct CAPP
subpartition can be selected also outside of the flash API.

Signed-off-by: Claudio Carvalho <cclaudio at linux.vnet.ibm.com>
---
 core/flash.c      | 144 +++++++++++++++++++++++++++++++-----------------------
 include/skiboot.h |   4 +-
 2 files changed, 86 insertions(+), 62 deletions(-)

diff --git a/core/flash.c b/core/flash.c
index 0424479..24c34cf 100644
--- a/core/flash.c
+++ b/core/flash.c
@@ -457,8 +457,7 @@ static int flash_find_subpartition(struct blocklevel_device *bl, uint32_t subid,
 				   bool ecc)
 {
 	struct flash_hostboot_header *header;
-	char eyecatcher[5];
-	uint32_t i, partsize;
+	uint32_t partsize, offset, size;
 	int rc;
 
 	header = malloc(FLASH_SUBPART_HEADER_SIZE);
@@ -478,66 +477,19 @@ static int flash_find_subpartition(struct blocklevel_device *bl, uint32_t subid,
 		goto end;
 	}
 
-	/* Perform sanity */
-	i = be32_to_cpu(header->version);
-	if (i != 1) {
-		prerror("FLASH: flash subpartition TOC version unknown %i\n", i);
-		rc = OPAL_RESOURCE;
+	rc = flash_subpart_info(header, partsize, subid, &offset, &size);
+	if (rc)
 		goto end;
-	}
-	/* NULL terminate eyecatcher */
-	strncpy(eyecatcher, header->eyecatcher, 4);
-	eyecatcher[4] = 0;
-	prlog(PR_DEBUG, "FLASH: flash subpartition eyecatcher %s\n",
-			eyecatcher);
-
-	rc = OPAL_RESOURCE;
-	for (i = 0; i< FLASH_HOSTBOOT_TOC_MAX_ENTRIES; i++) {
-		uint32_t ec, offset, size;
-
-		ec = be32_to_cpu(header->toc[i].ec);
-		offset = be32_to_cpu(header->toc[i].offset);
-		size = be32_to_cpu(header->toc[i].size);
-		/* Check for null terminating entry */
-		if (!ec && !offset && !size) {
-			prerror("FLASH: flash subpartition not found.\n");
-			goto end;
-		}
-
-		if (ec != subid)
-			continue;
 
-		/* Sanity check the offset and size. */
-		if (offset + size > partsize) {
-			prerror("FLASH: flash subpartition too big: %i\n", i);
-			goto end;
-		}
-		if (!size) {
-			prerror("FLASH: flash subpartition zero size: %i\n", i);
-			goto end;
-		}
-		if (offset < FLASH_SUBPART_HEADER_SIZE) {
-			prerror("FLASH: flash subpartition "
-					"offset too small: %i\n", i);
-			goto end;
-		}
-
-		prlog(PR_DEBUG, "FLASH: flash found subpartition: "
-				"%i size: %i offset %i\n",
-				i, size, offset);
-
-		/*
-		 * Adjust the start and size.  The start location in the needs
-		 * to account for ecc but the size doesn't.
-		 */
-		*start += offset;
-		*total_size = size;
-		if (ecc) {
-			*start += ecc_size(offset);
-			*total_size += ecc_size(size);
-		}
-		rc = 0;
-		goto end;
+	/*
+	 * Adjust the start and size.  The start location in the needs
+	 * to account for ecc but the size doesn't.
+	 */
+	*start += offset;
+	*total_size = size;
+	if (ecc) {
+		*start += ecc_size(offset);
+		*total_size += ecc_size(size);
 	}
 
 end:
@@ -651,7 +603,7 @@ static int flash_load_resource(enum resource_id id, uint32_t subid,
 
 	rc = flash_read_corrected(flash->bl, part_start, buf, size, ecc);
 	if (rc) {
-		prerror("FLASH: failed to read %s partition\n", name);
+		prerror("FLASH: failed to read %s partition, rc %d\n", name, rc);
 		goto out_free_ffs;
 	}
 
@@ -779,3 +731,73 @@ int flash_start_preload_resource(enum resource_id id, uint32_t subid,
 
 	return OPAL_SUCCESS;
 }
+
+int flash_subpart_info(void *part_header, uint32_t part_size, uint32_t subid,
+		       uint32_t *offset, uint32_t *size)
+{
+	struct flash_hostboot_header *header;
+	char eyecatcher[5];
+	uint32_t i, ec;
+
+	if (!part_header || !offset || !size) {
+		prlog(PR_ERR, "FLASH: invalid parameters: "
+		      "ph %p of %p sz %p\n", part_header, offset, size);
+		return OPAL_PARAMETER;
+	}
+
+	header = (struct flash_hostboot_header*) part_header;
+
+	/* Perform sanity */
+	i = be32_to_cpu(header->version);
+	if (i != 1) {
+		prerror("FLASH: flash subpartition TOC version unknown %i\n", i);
+		goto end;
+	}
+
+	/* NULL terminate eyecatcher */
+	strncpy(eyecatcher, header->eyecatcher, 4);
+	eyecatcher[4] = '\0';
+	prlog(PR_DEBUG, "FLASH: flash subpartition eyecatcher %s\n",
+			eyecatcher);
+
+	for (i = 0; i < FLASH_HOSTBOOT_TOC_MAX_ENTRIES; i++) {
+
+		ec = be32_to_cpu(header->toc[i].ec);
+		*offset = be32_to_cpu(header->toc[i].offset);
+		*size = be32_to_cpu(header->toc[i].size);
+
+		/* Check for null terminating entry */
+		if (!ec && !*offset && !*size) {
+			prerror("FLASH: flash subpartition not found.\n");
+			goto end;
+		}
+
+		if (ec != subid)
+			continue;
+
+		/* Sanity check the offset and size. */
+		if (*offset + *size > part_size) {
+			prerror("FLASH: flash subpartition too big: %i\n", i);
+			goto end;
+		}
+		if (!*size) {
+			prerror("FLASH: flash subpartition zero size: %i\n", i);
+			goto end;
+		}
+		if (*offset < FLASH_SUBPART_HEADER_SIZE) {
+			prerror("FLASH: flash subpartition "
+					"offset too small: %i\n", i);
+			goto end;
+		}
+
+		prlog(PR_DEBUG, "FLASH: flash found subpartition: "
+				"%i size: %i offset %i\n",
+				i, *size, *offset);
+
+		return OPAL_SUCCESS;
+	}
+end:
+	*size = 0;
+	*offset = 0;
+	return OPAL_RESOURCE;
+}
diff --git a/include/skiboot.h b/include/skiboot.h
index 52a235b..2a9f5e2 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -223,7 +223,9 @@ extern int flash_start_preload_resource(enum resource_id id, uint32_t subid,
 extern int flash_resource_loaded(enum resource_id id, uint32_t idx);
 extern bool flash_reserve(void);
 extern void flash_release(void);
-
+extern int flash_subpart_info(void *part_header, uint32_t part_size,
+			      uint32_t subid, uint32_t *offset,
+			      uint32_t *size);
 
 /* NVRAM support */
 extern void nvram_init(void);
-- 
1.9.1



More information about the Skiboot mailing list