[Skiboot] [PATCH 1/4] core/flash: Move subpartition locating logic out into own file, add tests

Stewart Smith stewart at linux.vnet.ibm.com
Tue Oct 25 18:14:59 AEDT 2016


A unit test for parsing sub-partition info is useful for a number
of reasons, one of which showed its head during development of
secure/trusted boot.

This patch just moves things around, there's no functional changes.

Signed-off-by: Stewart Smith <stewart at linux.vnet.ibm.com>
---
 core/Makefile.inc                  |   1 +
 core/flash-subpartition.c          | 102 +++++++++++++++++++++++++++++++++++++
 core/flash.c                       |  73 --------------------------
 core/test/Makefile.check           |   1 +
 core/test/run-flash-subpartition.c |  55 ++++++++++++++++++++
 include/skiboot.h                  |   3 +-
 6 files changed, 161 insertions(+), 74 deletions(-)
 create mode 100644 core/flash-subpartition.c
 create mode 100644 core/test/run-flash-subpartition.c

diff --git a/core/Makefile.inc b/core/Makefile.inc
index be59bcac18f1..9223af1b9202 100644
--- a/core/Makefile.inc
+++ b/core/Makefile.inc
@@ -8,6 +8,7 @@ CORE_OBJS += pci-opal.o fast-reboot.o device.o exceptions.o trace.o affinity.o
 CORE_OBJS += vpd.o hostservices.o platform.o nvram.o nvram-format.o hmi.o
 CORE_OBJS += console-log.o ipmi.o time-utils.o pel.o pool.o errorlog.o
 CORE_OBJS += timer.o i2c.o rtc.o flash.o sensor.o ipmi-opal.o
+CORE_OBJS += flash-subpartition.o
 
 ifeq ($(SKIBOOT_GCOV),1)
 CORE_OBJS += gcov-profiling.o
diff --git a/core/flash-subpartition.c b/core/flash-subpartition.c
new file mode 100644
index 000000000000..ba7f0a37829a
--- /dev/null
+++ b/core/flash-subpartition.c
@@ -0,0 +1,102 @@
+/* Copyright 2013-2016 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <skiboot.h>
+#include <opal-api.h>
+
+struct flash_hostboot_toc {
+	be32 ec;
+	be32 offset; /* From start of header.  4K aligned */
+	be32 size;
+};
+#define FLASH_HOSTBOOT_TOC_MAX_ENTRIES ((FLASH_SUBPART_HEADER_SIZE - 8) \
+		/sizeof(struct flash_hostboot_toc))
+
+struct flash_hostboot_header {
+	char eyecatcher[4];
+	be32 version;
+	struct flash_hostboot_toc toc[FLASH_HOSTBOOT_TOC_MAX_ENTRIES];
+};
+
+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/core/flash.c b/core/flash.c
index 92de42117ca0..4b7f4b38ea46 100644
--- a/core/flash.c
+++ b/core/flash.c
@@ -418,9 +418,6 @@ static struct {
 	{ RESOURCE_ID_CAPP,	RESOURCE_SUBID_SUPPORTED,	"CAPP" },
 };
 
-/* This mimics the hostboot SBE format */
-#define FLASH_SUBPART_ALIGNMENT 0x1000
-#define FLASH_SUBPART_HEADER_SIZE FLASH_SUBPART_ALIGNMENT
 
 struct flash_hostboot_toc {
 	be32 ec;
@@ -723,73 +720,3 @@ 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/core/test/Makefile.check b/core/test/Makefile.check
index fa1b806d2792..d3dd2600a230 100644
--- a/core/test/Makefile.check
+++ b/core/test/Makefile.check
@@ -1,5 +1,6 @@
 # -*-Makefile-*-
 CORE_TEST := core/test/run-device \
+	core/test/run-flash-subpartition \
 	core/test/run-mem_region \
 	core/test/run-malloc \
 	core/test/run-malloc-speed \
diff --git a/core/test/run-flash-subpartition.c b/core/test/run-flash-subpartition.c
new file mode 100644
index 000000000000..169362ef72cb
--- /dev/null
+++ b/core/test/run-flash-subpartition.c
@@ -0,0 +1,55 @@
+/* Copyright 2013-2016 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <skiboot.h>
+#include <opal-api.h>
+#include <stdlib.h>
+
+#include "../flash-subpartition.c"
+#include <assert.h>
+
+/* This is a straight dump of the CAPP ucode partition header */
+char capp[4096] = {0x43, 0x41, 0x50, 0x50, 0x00, 0x00, 0x00, 0x01,
+		   0x00, 0x01, 0x00, 0xea, 0x00, 0x00, 0x10, 0x00,
+		   0x00, 0x00, 0x8e, 0x50, 0x00, 0x02, 0x00, 0xea,
+		   0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x8e, 0x50,
+		   0x00, 0x02, 0x00, 0xef, 0x00, 0x00, 0x10, 0x00,
+		   0x00, 0x00, 0x8e, 0x50, 0x00, 0x02, 0x01, 0xef,
+		   0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x8e, 0x50,
+		   0x00, 0x01, 0x00, 0xd3, 0x00, 0x00, 0x10, 0x00,
+		   0x00, 0x00, 0x8e, 0x50, 0x00, 0x00, 0x00, 0x00 };
+
+int main(void)
+{
+	int rc;
+	uint32_t offset;
+	uint32_t size;
+	uint32_t subids[] = { 0x100ea, 0x200ea, 0x200ef, 0x201ef, 0x100d3 };
+
+	for (int i = 0; i < sizeof(subids)/sizeof(uint32_t); i++) {
+		offset = 0;
+		rc = flash_subpart_info(capp, 0x24000, subids[i],
+					&offset, &size);
+		printf("\nsubid %x\n", subids[i]);
+		printf("offset %u\n", offset);
+		printf("size %u\n", size);
+		assert (rc == 0);
+		assert (size == 36432);
+		assert (offset == 4096);
+	}
+
+	return 0;
+}
diff --git a/include/skiboot.h b/include/skiboot.h
index 2ef76771c97f..30149a1ac999 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -225,10 +225,11 @@ 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);
+#define FLASH_SUBPART_ALIGNMENT 0x1000
+#define FLASH_SUBPART_HEADER_SIZE FLASH_SUBPART_ALIGNMENT
 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);
 extern void nvram_read_complete(bool success);
-- 
2.1.4



More information about the Skiboot mailing list