aboutsummaryrefslogtreecommitdiff
path: root/core/flash.c
diff options
context:
space:
mode:
authorClaudio Carvalho <cclaudio@linux.vnet.ibm.com>2016-09-28 05:10:53 -0300
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-10-10 15:29:36 +1100
commitbd4038dc52b469e471f8adff4a8cfc0d475ff49d (patch)
tree504a61b1dc6eefa8c4372e11f04e42c036d5fb23 /core/flash.c
parenta857bdb7703b13799dcc19578c419ab3bee9f3fd (diff)
downloadskiboot-bd4038dc52b469e471f8adff4a8cfc0d475ff49d.zip
skiboot-bd4038dc52b469e471f8adff4a8cfc0d475ff49d.tar.gz
skiboot-bd4038dc52b469e471f8adff4a8cfc0d475ff49d.tar.bz2
core: add flash_subpart_info()
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@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core/flash.c')
-rw-r--r--core/flash.c144
1 files changed, 83 insertions, 61 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;
+}